Call failed in C ++ library with Perl using SWIG (AIX 5.1)

I am trying to call a C ++ library from Perl on an AIX 5.1 machine. I created a very simple test project to try this.

My C ++ library ( test.cpp ):

 #include <stdio.h> #include <iostream> void myfunc() { printf("in myfunc()\n"); std::cout << "in myfunc() also" << std::endl; } 

My SWIG interface interface ( test.i ):

 %module test %{ void myfunc(); %} void myfunc(); 

Then I create a shared object as follows:

 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 test.so generic object that should be loadable in perl (via the generated test.pm SWIG). I have a very simple perl script to try to load a shared object and call one function that I export ( test.pl ):

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

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

in myfunc ()
Illegal instruction (the kernel is reset)

If I comment on using std::cout in myfunc , it works without problems. It seems that using something in C ++ STL causes a core dump (I tried just declaring std::vector and std::stringstream , both of which lead to a core dump). I can create a standalone C ++ executable that uses STL without any problems, only when called in my shared object when loading from perl, which I got into.

I also tried using xlc, not gcc, but I get the same result. I think there is some kind of funky linker flag that I need to go through to make sure all the links are going right? Any ideas are welcome ...

Edit: if I contact using gcc / xlc instead of directly calling the linker ( ld ), I immediately get a segmentation error. It seems like it crashes when perl tries to just load the shared library. The ld call, as I said, is the closest that I have it working, but I think that some libraries or special AIX linker flags for C ++ libraries may not be available.

Edit2: Well, it works for me. AIX is very fragile when it comes to links. I eventually came up with the following communication command, which seems to work 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 most relevant libraries I am associated with. It turns out that the order in which libraries are mentioned is also very important. Also note that this builds against Perl 5.6.0, which ships with AIX 5.1. I tried to create the same simple application against Perl 5.8.8, and it does not work. However, I am sure that a much more sensible binding method (using direct gcc / xlc instead of calling ld directly) seems to work better. So this problem is a bug in the Perl distribution or linker, or something like that.

Hope this helps some poor soul cursed having to work with AIX ...

+4
source share
2 answers

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

What I did on Linux after replicating your problem:

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

Then the problem disappeared.

(Trying to get the correct list of libraries for ld was too big, so I just told gcc to do this for me.)

+4
source

I don't know anything about SWIG, but you can also verify that it expects a function using cdecl (and not pascal, fastcall, or another calling convention). Using the wrong between tools can lead to "bad things" (usually stack damage, as far as I can tell).

0
source

Source: https://habr.com/ru/post/1277586/


All Articles