26

Ubuntu 11.04 で、OpenCV 2.3 から 2.4.2 を使用して C++ で Python モジュールを開発しています。OpenCV はソースからビルドされました。Ubuntu リポジトリのバージョンの OpenCV は使用していません。

私の Python モジュールは問題なくコンパイルされ、Python に正しく読み込まれます。ただし、このモジュールを Ubuntu 11.10 または 12.04 でコンパイルすると、Python でロードしようとすると、「未定義のシンボル」というメッセージとともに ImportError が発生します。

これは私がモジュールをコンパイルする方法です:

g++ -fPIC -shared `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy -o mymodule.so mymodule.cpp

これは「pkg-config --cflags --libs opencv」の出力です

-I/usr/local/include/opencv -I/usr/local/include  /usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_ts.so /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videostab.so

私が得るエラーは次のとおりです。

ImportError: /path/to/service/mymodule.so: undefined symbol: _ZN5CvSVMD1Ev

私の理解では、「未定義のシンボル」は通常、リンクされたライブラリのいずれにも特定のシンボルが見つからないことを意味します。しかし、このシンボルが libopencv_ml.so にあることはわかっています。これを実行すると、次のようになります。

$ nm -g  /usr/local/lib/libopencv_ml.so | grep _ZN5CvSVMD1Ev

私は得る:

000000000002fd40 T _ZN5CvSVMD1Ev

/usr/local/lib は動的リンカー キャッシュにあるようです。

$ cat /etc/ld.so.conf.d/libc.conf 
# libc default configuration
/usr/local/lib

そして、そのファイルもキャッシュにあります。

$ ldconfig -p | grep opencv | grep ml
        libopencv_ml.so.2.4 (libc6,x86-64) => /usr/local/lib/libopencv_ml.so.2.4
        libopencv_ml.so (libc6,x86-64) => /usr/local/lib/libopencv_ml.so

それで、私が間違っているかもしれない手がかりを教えてもらえますか?Python の実行時に共有ライブラリがロードされる方法で、Ubuntu 11.04 と 11.10 の間で何か変更がありましたか? それともOpenCVの問題ですか?

4

1 に答える 1

25

解決策は、g ++コマンドラインで、生成されたモジュール名を、依存する他のモジュールの前に配置することです。

g++ -fPIC -shared -o mymodule.so mymodule.cpp `pkg-config --cflags --libs python` `pkg-config --cflags --libs opencv` -I/usr/local/include/opencv2/legacy

gccのmanページには、-lオプションについて記載されています。

コマンドのどこにこのオプションを書くかによって違いが生じます。リンカは、指定された順序でライブラリとオブジェクトファイルを検索して処理します。したがって、foo.o -lz bar.oファイルfoo.oの後、bar.oの前でライブラリzを検索します。bar.oがzの関数を参照している場合、それらの関数はロードされない可能性があります。

mymodule.soの名前は、リンク先のライブラリの前に指定されていたため、実際には、生成された.soファイルにリンクされていませんでした。

仕組みを指摘してくれた@JFSebastianに感謝します-l

于 2012-07-26T06:07:16.293 に答える