使用SWIG从Perl调用C ++库时崩溃(AIX 5.1)

时间:2008-10-08 21:53:23

标签: c++ perl swig aix

我正试图在AIX 5.1机器上从Perl调用C ++库。我已经创建了一个非常简单的测试项目,试图运用它。

我的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()中   非法指令(核心倾销)

如果我在std::cout中评论myfunc用法,则可以正常运行。似乎在C ++ STL中使用任何内容都会导致核心转储(我尝试声明std::vectorstd::stringstream,这两者都会导致核心转储)。我可以创建一个独立的C ++可执行文件,它使用STL而没有任何问题,只有在从perl加载时我的共享对象中调用才会遇到麻烦。

我也试过使用xlc而不是gcc,但我得到的结果相同。我想我需要传递一些时髦的链接器标志,以确保所有链接都正确发生?欢迎任何想法......

编辑:如果我使用gcc / xlc链接而不是直接调用链接器(ld),我会立即得到分段错误。当perl试图简单地加载共享库时,它看起来崩溃了。如上所述调用ld是我最接近它的工作,但我想我可能缺少一些库或C ++库的特殊AIX链接器标志。

Edit2:好的,我已经开始工作了。在链接方面,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合作而受到诅咒的可怜的灵魂......

2 个答案:

答案 0 :(得分:4)

难道你不只是将你的libstdc ++添加到ld命令中吗?例如,-lstdc++

在复制问题之后,我在Linux上所做的是:

gcc -g -lstdc++ -shared test*.o -o test.so

然后问题就消失了。

(试图为ld获取正确的库列表是太多的工作,所以我只是告诉gcc为我做这件事。)

答案 1 :(得分:0)

我对SWIG一无所知,但您可能还想检查它是否期望使用cdecl的函数(而不是pascal,fastcall或其他一些调用约定)。在工具之间使用错误的方法可能会导致“不良事件发生”(据我所知,通常是堆栈损坏)。