使用SWIG(AIX 5.1)从Perl调用C ++库时崩溃 [英] Crash when calling into C++ library from Perl using SWIG (AIX 5.1)

查看:203
本文介绍了使用SWIG(AIX 5.1)从Perl调用C ++库时崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在AIX 5.1机器上调用Perl的C ++库。我创建了一个非常简单的测试项目来尝试这个。



我的C ++共享库( test.cpp ):

  #include< stdio.h> 
#include< iostream>

void myfunc()
{
printf(in myfunc()\\\
);
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

应该可以在perl中加载的一个 test.so 共享对象(通过SWIG生成的 test.pm )。我有一个非常简单的perl脚本来尝试加载共享对象并调用我正在导出的一个函数( test.pl ):

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

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

在myfunc()中

非法指令b $ b

如果我在中注释掉 std :: cout ,它工作没有问题。看起来好像使用C ++ STL中的任何东西导致核心转储(我试图只是声明一个 std :: vector std :: stringstream ,都会导致核心转储)。我可以创建一个独立的C ++可执行文件使用STL没有任何问题,只有当我从共享对象中调用时,从perl加载,我陷入麻烦。



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



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



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 

我链接的库是最相关的。事实证明,库的顺序是非常重要的(ugh)。还要注意,这是针对AIX 5.1附带的Perl 5.6.0构建的。我试着构建这个简单的应用程序对Perl 5.8.8,它不工作。但是,我很确定更连贯的方法(使用直接 gcc / xlc 调用 ld 直接)似乎工作更好。所以这个问题似乎是在Perl发行版或链接器或某事中的一个错误。



希望这将帮助一些可怜的灵魂诅咒与不得不与AIX一起工作...

解决方案

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



我在linux上做了什么,复制你的问题后:

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

然后问题消失了。



(尝试获取ld的库的正确列表是太多的工作,所以我只是告诉gcc做它me。)


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.

My C++ shared library (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):

%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):

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

When I run test.pl, I get the following output:

in myfunc()
Illegal instruction (core dumped)

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.

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...

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.

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:

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.

Hopefully this will help some poor soul cursed with having to work with AIX...

解决方案

Wouldn't you just add your libstdc++ to your ld command? e.g., "-lstdc++"?

What I did on linux, after replicating your problem was:

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.)

这篇关于使用SWIG(AIX 5.1)从Perl调用C ++库时崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆