使用 SWIG (AIX 5.1) 从 Perl 调用 C++ 库时崩溃
Posted
技术标签:
【中文标题】使用 SWIG (AIX 5.1) 从 Perl 调用 C++ 库时崩溃【英文标题】:Crash when calling into C++ library from Perl using SWIG (AIX 5.1) 【发布时间】:2010-09-16 03:38:00 【问题描述】:我试图在 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() 非法指令(核心转储)
如果我注释掉myfunc
中的std::cout
用法,它可以正常工作。似乎在 C++ STL 中使用任何东西都会导致核心转储(我尝试只声明 std::vector
和 std::stringstream
,两者都会导致核心转储)。我可以毫无问题地创建一个使用 STL 的独立 C++ 可执行文件,只有在从 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 的可怜的灵魂......
【问题讨论】:
非常感谢!这非常有用。不幸的是它很难找到,所以我写了一个类似的问题希望也能帮助其他人:***.com/questions/1735199/… 【参考方案1】:您不只是将您的 libstdc++ 添加到您的 ld 命令吗?例如,-lstdc++
?
复制您的问题后,我在 Linux 上所做的是:
gcc -g -lstdc++ -shared test*.o -o test.so
然后问题就解决了。
(试图为 ld 获取正确的库列表是太多的工作,所以我只是告诉 gcc 为我做这件事。)
【讨论】:
【参考方案2】:我对 SWIG 一无所知,但您可能还想检查它是否需要使用 cdecl(而不是 pascal、fastcall 或其他一些调用约定)的函数。在工具之间使用错误的工具可能会导致“坏事发生”(据我所知,通常是堆栈损坏)。
【讨论】:
以上是关于使用 SWIG (AIX 5.1) 从 Perl 调用 C++ 库时崩溃的主要内容,如果未能解决你的问题,请参考以下文章
如何为 wchar_t 定义 swig typmap 以与 Perl 脚本绑定?