0

我正在使用calculator-server.c++示例,我尝试从中提取thisCap()以从外部访问服务器的功能。因为thisCap()protected,我写了自己的公众号getCapability()

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

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

然后我创建服务器并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 ()

按照源代码,我最终得到了这个

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

所以它似乎thisHook是一个 nullptr,这是有道理的,因为这就是它的初始化方式

我只是不知道它在什么时候被初始化(解释了它何时绝对没有被初始化)。

任何的想法?

4

1 回答 1

1

thisCap()仅在创建了至少一个Client指向您的服务器对象的对象后才有效。要创建该 initial Client,您可以简单地声明一个客户端类型的变量并将其初始化为您的服务器对象,如下所示:

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

如果您想在构造 a 之后保留对底层服务器对象的引用Client,您可以执行以下操作:

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

请注意,一旦Client创建了第一个,一旦不再有任何Client指向它的 s(包括 remote Clients),服务器就会被销毁。因此,如果您想确保您的参考保持有效,请确保您还保留一份Client.

通常,thisCap()在 RPC 方法的实现中使用。以您使用getCapability()方法的方式将其公开给外部调用者是不寻常的。这是因为如果调用者还没有持有一个Client指向该对象的指针,那么它就无法知道该对象是否仍然存在,因此调用类似getCapability().

于 2020-10-16T02:18:38.607 回答