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