I'm trying to call into a C++ library from Perl on an AIX 5.1 machine. I've created a very simple test project to try to exercise this.
我试图在AIX 5.1机器上从Perl调用C ++库。我创建了一个非常简单的测试项目来尝试练习这个。
My C++ shared library (test.cpp
):
我的C ++共享库(test.cpp):
#include <stdio.h>
#include <iostream>
void myfunc()
{
printf("in myfunc()\n");
std::cout << "in myfunc() also" << std::endl;
}
My SWIG interface file (test.i
):
我的SWIG接口文件(test.i):
%module test
%{
void myfunc();
%}
void myfunc();
I then build the shared object like so:
然后我像这样构建共享对象:
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
At this point, I have a test.so
shared object that should be loadable in perl (via the SWIG generated test.pm
). I have a very simple perl script to try to load the shared object and call the one function that I am exporting (test.pl
):
此时,我有一个test.so共享对象,应该可以在perl中加载(通过SWIG生成的test.pm)。我有一个非常简单的perl脚本来尝试加载共享对象并调用我正在导出的一个函数(test.pl):
#!/usr/bin/perl
use test;
test::myfunc();
When I run test.pl
, I get the following output:
当我运行test.pl时,我得到以下输出:
in myfunc()
Illegal instruction (core dumped)in myfunc()非法指令(核心转储)
If I comment-out the std::cout
usage in myfunc
, it works without problem. It appears as though using anything in the C++ STL causes a core dump (I tried just declaring a std::vector
and std::stringstream
, both result in the core dump). I can create a standalone C++ executable that uses the STL without any issues, it's only when called in my shared object when loaded from perl that I get into trouble.
如果我在myfunc中注释掉std :: cout用法,它的工作没有问题。似乎在C ++ STL中使用任何东西都会导致核心转储(我试图声明一个std :: vector和std :: stringstream,两者都会导致核心转储)。我可以创建一个独立的C ++可执行文件,它使用STL而没有任何问题,只有在从perl加载时我的共享对象中调用才会遇到麻烦。
I've also tried using xlc rather than gcc, but I get the same result. I'm thinking there is some funky linker flag that I need to pass in to ensure that all of the linkage occurs correctly? Any ideas are welcome...
我也试过使用xlc而不是gcc,但我得到了相同的结果。我想我需要传递一些时髦的链接器标志,以确保所有链接都正确发生?欢迎任何想法......
Edit: If I link using gcc
/xlc
instead of invoking the linker directly (ld
), I immediately get a segmentation fault. It looks like it crashes when perl is trying to simply load the shared library. Calling ld
as I have above is the closest that I've got it to working, but I think I may be missing some libraries or special AIX linker flags for the C++ libraries.
编辑:如果我使用gcc / xlc链接而不是直接调用链接器(ld),我立即得到分段错误。当perl试图简单地加载共享库时,它看起来像崩溃了。如上所述调用ld是我最接近它的工作,但我想我可能缺少一些库或C ++库的特殊AIX链接器标志。
Edit2: Ok, I've got it working. AIX is very fragile when it comes to linking. I ultimately came up with the following link command that seems to be working correctly:
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
The libraries that I linked against are the most relevant. It turns out that the order in which the libraries are mentioned is very important also (ugh). Also note that this is being built against Perl 5.6.0 that ships with AIX 5.1. I've tried building this same simple application against Perl 5.8.8 and it doesn't work. However, I'm pretty sure the much more sane method of linking (using straight gcc
/xlc
instead of having to call ld
directly) seems to work better. So this issue appears to be a bug in the Perl distribution or the linker or something.
我链接的库是最相关的。事实证明,提到图书馆的顺序也非常重要(呃)。另请注意,这是针对AIX 5.1附带的Perl 5.6.0构建的。我已经尝试针对Perl 5.8.8构建这个相同的简单应用程序,但它不起作用。但是,我很确定更直接的链接方法(使用直接gcc / xlc而不是直接调用ld)似乎效果更好。所以这个问题似乎是Perl发行版或链接器中的一个错误。
Hopefully this will help some poor soul cursed with having to work with AIX...
希望这将有助于一些可怜的灵魂被诅咒与AIX合作......
2 个解决方案
#1
4
Wouldn't you just add your libstdc++ to your ld command? e.g., -lstdc++
?
你不是只是将你的libstdc ++添加到ld命令中吗?例如,-lstdc ++?
What I did on Linux, after replicating your problem was:
复制问题后,我在Linux上做了什么:
gcc -g -lstdc++ -shared test*.o -o test.so
Then the problem went away.
然后问题就消失了。
(Trying to get the exact right list of libraries for ld was too much work, so I just told gcc to do it for me.)
(试图为ld获取正确的库列表是太多的工作,所以我只是告诉gcc为我做这件事。)
#2
0
I know nothing about SWIG, but you might also want to check that it's expecting a function using cdecl (rather than pascal, fastcall, or some other calling convention). Using the wrong one between tools can lead to "bad things happening" (usually stack corruption, as far as I can tell).
我对SWIG一无所知,但您可能还想检查它是否期望使用cdecl(而不是pascal,fastcall或其他一些调用约定)的函数。在工具之间使用错误的方法可能导致“不良事件发生”(通常是堆栈损坏,据我所知)。
#1
4
Wouldn't you just add your libstdc++ to your ld command? e.g., -lstdc++
?
你不是只是将你的libstdc ++添加到ld命令中吗?例如,-lstdc ++?
What I did on Linux, after replicating your problem was:
复制问题后,我在Linux上做了什么:
gcc -g -lstdc++ -shared test*.o -o test.so
Then the problem went away.
然后问题就消失了。
(Trying to get the exact right list of libraries for ld was too much work, so I just told gcc to do it for me.)
(试图为ld获取正确的库列表是太多的工作,所以我只是告诉gcc为我做这件事。)
#2
0
I know nothing about SWIG, but you might also want to check that it's expecting a function using cdecl (rather than pascal, fastcall, or some other calling convention). Using the wrong one between tools can lead to "bad things happening" (usually stack corruption, as far as I can tell).
我对SWIG一无所知,但您可能还想检查它是否期望使用cdecl(而不是pascal,fastcall或其他一些调用约定)的函数。在工具之间使用错误的方法可能导致“不良事件发生”(通常是堆栈损坏,据我所知)。