gpt4 book ai didi

c++ - Perl:IPC::Shareable 和 SWIG'ed C++ 对象不一致

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:41:23 32 4
gpt4 key购买 nike

对于我的某个 Perl 项目,我需要多个 Perl 进程共享一些位于 C++ 库中的资源。 (别问,这不是这个问题的核心,只是上下文。)

因此,我试图在这种情况下深入研究两个"new"领域: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

很明显,数组引用得到了共享,但客户端没有“看到”服务器的 example::Rectangle,而是在一 block (零初始化的)流氓内存上工作,而这又是服务器对……一无所知

我怀疑我必须对 $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 模块提供的用于序列化对象的 Hook 。就消息传递/队列而言,我很喜欢使用 ZeroMQ,它为您提供了一个简单的类似套接字的接口(interface)。

关于c++ - Perl:IPC::Shareable 和 SWIG'ed C++ 对象不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7518181/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com