我希望您能够在AIX 5.1机器上从Perl调用C++库。我创建了一个非常简单的测试项目来尝试实现这一目标。
我的C++共享库(test.cpp):
我然后这样构建共享对象:
当我运行
我也尝试使用xlc而不是gcc,但结果相同。我认为需要传递某些奇怪的链接器标志,以确保所有链接发生正确?欢迎任何想法...
编辑:如果我使用
编辑2:好了,我让它正常工作了。对于链接来说,AIX非常脆弱。我最终想出了以下链接命令,似乎可以正常工作:
我链接的库是最相关的。提到库的顺序也非常重要(唉)。请注意,这是针对AIX 5.1附带的Perl 5.6.0构建的。我尝试使用Perl 5.8.8构建相同的简单应用程序,但它不起作用。然而,我相信使用直接的gcc/xlc链接(而不是直接调用ld)似乎更加合理。所以,这个问题似乎是Perl分发或链接器或其他什么东西的一个错误。
希望这能帮助那些不得不使用AIX的可怜人...
我的C++共享库(test.cpp):
#include <stdio.h>
#include <iostream>
void myfunc()
{
printf("in myfunc()\n");
std::cout << "in myfunc() also" << std::endl;
}
我的 SWIG 接口文件 (test.i
):
%module test
%{
void myfunc();
%}
void myfunc();
我然后这样构建共享对象:
swig -c++ -perl test.i
g++ -c test_wrap.cxx -I/usr/opt/perl5/lib/5.6.0/aix/CORE -o test_wrap.o
g++ -c test.cpp -o test.o
ld -G -bI:/usr/opt/perl5/lib/5.6.0/aix/CORE/perl.exp -bnoentry -bexpall -lc_r test.o test_wrap.o -o test.so
此时,我有一个名为test.so
的共享对象,应该可以通过SWIG生成的test.pm
在perl中加载。我有一个非常简单的perl脚本来尝试加载共享对象并调用我正在导出的一个函数(test.pl
):
#!/usr/bin/perl
use test;
test::myfunc();
当我运行
test.pl
时,我会得到以下输出:
如果我将在myfunc()函数中
非法指令 (核心已转储)
myfunc
中的std::cout
注释掉,则可以正常工作。看起来似乎使用C++ STL中的任何内容都会导致核心转储(我尝试了只声明std::vector
和std::stringstream
,两者都导致核心转储)。我可以创建一个独立的C++可执行文件,使用STL没有任何问题,只有在从perl加载时调用共享对象时才会遇到麻烦。我也尝试使用xlc而不是gcc,但结果相同。我认为需要传递某些奇怪的链接器标志,以确保所有链接发生正确?欢迎任何想法...
编辑:如果我使用
gcc
/xlc
进行链接而不是直接调用链接器ld
,我会立即得到一个分段错误。看起来它在尝试简单加载共享库时崩溃了。像上面那样调用ld
是我最接近使它工作的方法,但我认为我可能缺少一些库或C++库的特殊AIX链接器标志。编辑2:好了,我让它正常工作了。对于链接来说,AIX非常脆弱。我最终想出了以下链接命令,似乎可以正常工作:
ld -G -bI:/usr/opt/perl5/lib/5.6.0/aix/CORE/perl.exp -bnoentry -bexpall -lC -lc -ldl test.o test_wrap.o -o test.so
我链接的库是最相关的。提到库的顺序也非常重要(唉)。请注意,这是针对AIX 5.1附带的Perl 5.6.0构建的。我尝试使用Perl 5.8.8构建相同的简单应用程序,但它不起作用。然而,我相信使用直接的gcc/xlc链接(而不是直接调用ld)似乎更加合理。所以,这个问题似乎是Perl分发或链接器或其他什么东西的一个错误。
希望这能帮助那些不得不使用AIX的可怜人...