我试图在AIX 5.1机器上从Perl调用C++库。我已经创建了一个非常简单的测试项目来尝试执行此操作。使用SWIG从Perl调用C++库时发生崩溃(AIX 5.1)
我的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
共享对象应该可以在perl中加载(通过SWIG生成的test.pm
)。我有一个非常简单的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
),我立即得到一个分段错误。它看起来像当perl试图简单地加载共享库时崩溃。如上所述,调用ld
是我最接近的工作方式,但我想我可能会缺少某些库或AIX 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工作诅咒...
非常感谢!这非常有用。不幸的是,它很难找到,所以我写了一个类似的问题,希望能够帮助其他人:http://stackoverflow.com/questions/1735199/swig-crashes-on-aix-with-python-and-probably-everything-否则,痛饮支持/ 1735313 – Davide 2009-11-14 19:28:08