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

时间:2011-09-22 16:25:01

标签: c++ perl ipc swig

对于我的某个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

显然,数组引用可以共享,但是客户端没有“看到”服务器的示例:: Rectangle,而是在一个(零初始化的)流氓内存上工作,而后者依次是服务器什么都不知道...

我怀疑我必须对$v_rect做一些事情以使其正常工作,但我在OO Perl中不够坚实,不知道是什么。有人救人吗?

1 个答案:

答案 0 :(得分:3)

你要做的事情是行不通的。你将不得不咬紧牙关并做一些形式的消息传递。

我不太清楚SWIG如何为Perl包装C(++)级别的对象,但它很可能是通常的,在整数槽中可怕的“指针”策略。在此设置中,它将分配一个C(++)对象并在Perl标量中存储指向它的指针。 Perl对象将成为这个标量的祝福参考。当对Perl对象的所有引用都消失时,Perl类的析构函数将显式释放C(++)对象。一种更现代的技术就像XS :: Object :: Magic模块允许你做的那样。

但是包装器的细节甚至都不重要。重要的是对象是不透明到Perl!通过联系,IPC :: Shareable无论如何都使用了一些时尚和坦率的脆弱技术。它可能适用于您的Perl对象,也可能不适用。但是当您共享Perl对象时,C(++)对象将 NOT 被共享。怎么可能呢? Perl对此一无所知。它不可能。

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