Perl: IPC::可共享和SWIG C++对象不同意
Perl: IPC::Shareable and SWIG'ed C++ object don't agree
对于我的某个Perl项目,我需要几个Perl进程共享一些位于c++库中的资源。(不要问,这不是这个问题的核心,只是上下文。)
因此,在这种情况下,我试图深入研究两个"新"领域:IPC::Shareable
和使用SWIG包装c++。看来我做错了什么,这正是我想问的。
在c++端,我写了一个小的测试类Rectangle
,它有一个空的构造函数、一个set
和一个size
成员函数。
然后我把这个类包装在swig生成的Perl包example
中。
在Perl端,我尝试SWIG模块是否按预期工作:
use example;
my $testrec = new example::Rectangle;
$testrec->set( 6, 7 );
print $testrec->size() . "n";
打印"42",就像它应该的那样。
然后我试着测试我使用IPC::Shareable
的方法。我写了两个Perl脚本,一个"服务器"和一个"客户端",来测试资源共享。
:
use IPC::Shareable;
use example;
# v_ for variable, g_ for (IPC) glue
my $v_array;
my $v_rect;
my %options = ( create => 'yes', exclusive => 0, mode => 0644, destroy => 'yes' );
tie $v_array, 'IPC::Shareable', 'g_array', { %options } or die;
tie $v_rect, 'IPC::Shareable', 'g_rect', { %options } or die;
$v_array = [ "0" ];
$v_rect = new example::Rectangle;
$v_rect->set( 6, 7 );
while ( 1 ) {
print "server array: " . join( " - ", @$v_array ) . "n";
print "server rect: " . $v_rect->size() . "n";
sleep 3;
}
"客户":
use IPC::Shareable;
use example;
# v_ for variable, g_ for (IPC) glue
my $v_array;
my $v_rect;
my %options = ( create => 0, exclusive => 0, mode => 0644, destroy => 0 );
tie $v_array, 'IPC::Shareable', 'g_array', { %options } or die;
tie $v_rect, 'IPC::Shareable', 'g_rect', { %options } or die;
my $count = 0;
while ( 1 ) {
print "client array: " . join( " - ", @$v_array ) . "n";
print "client rect: " . $v_rect->size() . "n";
push( @$v_array, ++$count );
$v_rect->set( 3, $count );
sleep 3;
}
从"服务器"开始,然后是"客户端",我得到了"服务器"的输出:
server array: 0
server rect: 42
server array: 0 - 1
server rect: 42
server array: 0 - 1 - 2
server rect: 42
下面是"客户端"的输出:
client array: 0
client rect: 0
client array: 0 - 1
client rect: 3
client array: 0 - 1 - 2
client rect: 6
显然,数组引用得到了共享,但客户端没有"看到"服务器的示例::矩形,而是在(零初始化)的流氓内存上工作,而服务器对此一无所知…
我怀疑我必须对$v_rect
做些什么才能使这个工作正常,但我在OO Perl中不够扎实,不知道该怎么做。有人来救援吗?
你想做的事情是行不通的。你必须咬紧牙关,做某种形式的消息传递。
我不太记得SWIG是如何为Perl包装C(++)级对象的,但它很可能是通常的,公认的可怕的"整数槽中的指针"策略。在这个设置中,它将分配一个c++对象,并在Perl标量中存储指向该对象的指针。Perl对象将是对这个标量的引用。当对Perl对象的所有引用都消失时,c++对象将由Perl类的析构函数显式释放。一种更现代的技术是XS::Object::Magic模块允许您做的事情。
但是包装器的细节甚至不是那么重要。重要的是对象对Perl来说是不透明的 !对于连接,IPC::Shareable使用的是有些过时且脆弱的技术。它可能适合您的Perl对象,也可能不适合。但是当您共享Perl对象时,C(++)对象将而不是被共享。怎么可能呢?Perl对此一无所知。也不可能。
您应该从消息传递和序列化的角度来考虑问题。为了序列化C(++)对象,您需要允许C方面的一些合作。看一下Storable模块为序列化对象提供的钩子。就消息传递/队列而言,我喜欢使用ZeroMQ,它为您提供了一个简单的类似套接字的接口。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象