调用 `thisCap()` 段错误

Call to `thisCap()` segfaults

我正在玩 calculator-server.c++ 示例,我尝试在其中提取 thisCap() 以从外部访问服务器。因为thisCap()protected,所以我自己写的public getCapability():

class CalculatorImpl final: public Calculator::Server {
  // Implementation of the Calculator Cap'n Proto interface.

public:
  Calculator::Client getCapability() {
      return thisCap();
  }

然后我创建服务器并从我的 main:

调用 getCapability()
  auto calculatorImpl = kj::heap<CalculatorImpl>();
  auto myCapability = calculatorImpl->getCapability();

但是这个段错误:

Program received signal SIGSEGV, Segmentation fault.
0x000055555573c847 in capnp::Capability::Server::thisCap() ()
(gdb) bt
#0  0x000055555573c847 in capnp::Capability::Server::thisCap() ()
#1  0x000055555573c93d in Calculator::Server::thisCap() ()
#2  0x000055555573e541 in CalculatorImpl::getCapability() ()
#3  0x0000555555739a98 in main ()

根据来源,我最终在 this:

Capability::Client Capability::Server::thisCap() {
  return Client(thisHook->addRef());
}

所以看起来 thisHook 是一个 nullptr,这是有道理的,因为那是 how it is initialized

我只是不太明白它是在哪一点初始化的(this 解释了它何时绝对没有初始化)。

有什么想法吗?

thisCap() 仅在至少创建了一个 Client 指向您的服务器对象的对象后才起作用。要创建初始 Client,您只需声明一个客户端类型的变量并将其初始化为您的服务器对象,如下所示:

Calculator::Client cap = kj::heap<CalculatorImpl>();

如果你想在构建 Client 之后仍保留对底层服务器对象的引用,你可以这样做:

kj::Own<CalculatorImpl> server = kj::heap<CalculatorImpl>();
CalculatorImpl& ref = *server;
Calculator::Client cap = kj::mv(server);

请注意,一旦第一个 Client 创建完毕,一旦不再有任何 Client 指向它(包括远程 Client ),服务器将立即销毁).因此,如果您想确保您的参考保持有效,请确保您还保留了 Client.

的副本

通常,thisCap()用于RPC方法的实现。以使用 getCapability() 方法的方式将其公开给外部调用者是不寻常的。这是因为如果调用者还没有持有指向该对象的 Client ,那么它就无法知道该对象是否仍然存在,因此调用 [=21= 这样的方法是不安全的].