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
) ロード可能な共有オブジェクトができました。共有オブジェクトをロードして、エクスポートしている 1 つの関数を呼び出そうとする非常に単純な perl スクリプトがあります ( test.pl
)。
#!/usr/bin/perl
use test;
test::myfunc();
を実行するtest.pl
と、次の出力が得られます。
myfunc() の
不正な命令 (コアダンプ)
std::cout
の使い方をコメントアウトすればmyfunc
問題なく動作します。C++ STL で何かを使用するとコア ダンプが発生するように見えます (単に astd::vector
とを宣言しようとしましたstd::stringstream
が、どちらもコア ダンプになります)。STL を使用するスタンドアロンの C++ 実行可能ファイルを問題なく作成できます。問題が発生するのは、perl からロードされたときに共有オブジェクトで呼び出されたときだけです。
gcc ではなく xlc を使用してみましたが、同じ結果が得られます。すべてのリンケージが正しく行われるようにするために渡す必要があるファンキーなリンカ フラグがあると思いますか? どんなアイデアでも大歓迎です...
編集:リンカを直接呼び出す代わりにgcc
/を使用してリンクすると ( )、すぐにセグメンテーション違反が発生します。perl が単に共有ライブラリをロードしようとするとクラッシュするようです。上記のように呼び出すことは、動作に最も近いものですが、いくつかのライブラリまたは C++ ライブラリ用の特別な AIX リンカー フラグが不足している可能性があると思います。xlc
ld
ld
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
/を使用する) はるかに健全なリンク方法の方が適切に機能するように思われます。したがって、この問題は Perl ディストリビューションまたはリンカなどのバグのようです。xlc
ld
願わくば、これが AIX で作業しなければならないことで呪われた哀れな魂の助けになることを願っています...