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

4
我希望您能够在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的共享对象,应该可以通过SWIG生成的test.pm在perl中加载。我有一个非常简单的perl脚本来尝试加载共享对象并调用我正在导出的一个函数(test.pl):

#!/usr/bin/perl
use test;
test::myfunc();

当我运行test.pl时,我会得到以下输出:

在myfunc()函数中
非法指令 (核心已转储)

如果我将myfunc中的std::cout注释掉,则可以正常工作。看起来似乎使用C++ STL中的任何内容都会导致核心转储(我尝试了只声明std::vectorstd::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的可怜人...

非常感谢!这真是非常有用。不幸的是,它很难找到,所以我写了一个类似的问题,希望能帮助其他人:http://stackoverflow.com/questions/1735199/swig-crashes-on-aix-with-python-and-probably-everything-else-swig-support/1735313 - Davide
2个回答

4

您可以将您的libstdc++添加到ld命令中,例如-lstdc++

在Linux上,我遇到了与您相同的问题后所做的是:

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

然后问题就解决了。

(试图为ld获取精确的库列表太麻烦了,所以我让gcc替我完成了这项工作。)


0

我对SWIG一无所知,但你也许想检查一下它是否期望使用cdecl函数(而不是pascal、fastcall或其他调用约定)。在工具之间使用错误的调用约定可能会导致“坏事情发生”(就我所知,通常是堆栈损坏)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接