调用 `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= 这样的方法是不安全的].
我正在玩 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= 这样的方法是不安全的].