Perl:IPC :: Shareable和SWIG'ed C++对象不同意

Dev*_*lar 5 c++ perl swig ipc

对于我的某个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";
Run Code Online (Sandbox Code Playgroud)

这样打印"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;
}
Run Code Online (Sandbox Code Playgroud)

客户端":

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;
}
Run Code Online (Sandbox Code Playgroud)

首先启动"服务器",然后是"客户端",我得到"服务器"的输出:

server array: 0
server rect:  42
server array: 0 - 1
server rect:  42
server array: 0 - 1 - 2
server rect:  42
Run Code Online (Sandbox Code Playgroud)

而这个输出为"客户端":

client array: 0
client rect:  0
client array: 0 - 1
client rect:  3
client array: 0 - 1 - 2
client rect:  6
Run Code Online (Sandbox Code Playgroud)

显然,数组引用可以共享,但是客户端没有"看到"服务器的示例:: Rectangle,而是在一个(零初始化的)流氓内存上工作,反过来服务器一无所知...

我怀疑我必须做些什么来$v_rect使这项工作正常,但我在OO Perl中不够坚实,不知道是什么.谁来救援?

tse*_*see 3

你想做的事是行不通的。您将不得不硬着头皮进行某种形式的消息传递。

我不太记得 SWIG 是如何准确地包装 Perl 的 C(++) 级对象,但它很可能是常见的、不可否认的可怕的“整数槽中的指针”策略。在此设置中,它将分配一个 C(++) 对象并将指向它的指针存储在 Perl 标量中。Perl 对象将是对此标量的祝福引用。当对 Perl 对象的所有引用都消失时,C(++) 对象将由 Perl 类的析构函数显式释放。更现代的技术类似于 XS::Object::Magic 模块允许您执行的操作。

但包装的细节并不那么重要。重要的是该对象对于 Perl 来说是不透明的!就关系而言,IPC::Shareable 无论如何都使用了一些过时且坦率地说脆弱的技术。它可能适用于您的 Perl 对象,也可能不适用于您的 Perl 对象。但是当你共享 Perl 对象时,C(++) 对象将不会被共享。怎么可能呢?Perl对此一无所知。而且这不可能。

相反,您应该做的是考虑消息传递和序列化方面的问题。为了序列化您的 C(++) 对象,您需要允许 C 方面的一些合作。看一下 Storable 模块提供的用于序列化对象的钩子。就消息传递/队列而言,我很喜欢使用 ZeroMQ,它为您提供了一个简单的类似套接字的接口。