実現したいこと
事前にコンパイルされた静的ライブラリをpybind11を使ったラッパー関数を用意してPythonで呼び出したい。
言語間のバインディングについては知識が全くなく、以下のことが実現できるか教えて頂きたいです。
- 手元にソースコードがないC++のコードをPybind11を使って共有ライブラリを作ることでPythonから呼び出せるか?
以下の状況を考え、静的ライブラリのIFを知っていることを条件にラッパー関数作成しました。
bash
1. 2├── lib 3│ ├── hello.cpp // ソースコードは提供されないと仮定 4│ ├── hello.o // 同上 5│ └── libhello.a // 静的ライブラリ 6└── wrapper 7 ├── wrapper.cpp // 今回作成したラッパー用の関数 8 └── wrapper.cpython-37m-x86_64-linux-gnu.so // pybind11でビルドした共有ライブラリ
該当のソースコード
hello.cpp: 提供されない想定
c++
1#include <iostream> 2#include <string> 3 4void hello(const std::string &name) { 5 std::cout << "Hello " << name << std::endl; 6}
wrapper/wrapper.cpp: 静的ライブラリの関数を呼び出すためのラッパー関数
c++
1#include <pybind11/pybind11.h> 2#include <string> 3extern void hello(const std::string &name); 4 5int wrap_hello() { 6 hello("MAIN"); 7 return 0; 8} 9 10namespace py = pybind11; 11PYBIND11_MODULE(hello_wrap, m) { 12 m.doc() = "Hello wrapper"; 13 m.def("wrap_hello", &wrap_hello, "Call hello method"); 14}
wrapper.cpython-37m-x86_64-linux-gnu.so: pybind11 を使って共有ライブラリを作成
※yymmtさんの指摘により共有ライブラリのPrefixをPYBIND11_MODULEの第一引数に合わせました
bash
1g++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` wrapper.cpp -o hello_wrap`python3-config --extension-suffix`
発生している問題・エラーメッセージ
試しにPythonでモジュールをインポートすると静的ライブリで定義しているhelloが未定義だとエラーが出力されます。
bash
1$ python 2Python 3.7.3 (default, May 29 2019, 08:41:00) 3[GCC 7.4.0] on linux 4Type "help", "copyright", "credits" or "license" for more information. 5>>> import wrapper 6Traceback (most recent call last): 7 File "<stdin>", line 1, in <module> 8ImportError: /home/hogehoge/wrapper/wrapper.cpython-37m-x86_64-linux-gnu.so: undefined symbol: _Z5helloRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 9>>>
bash
1$ nm -C wrapper.cpython-37m-x86_64-linux-gnu.so |grep -i hello -A 1 20000000000004e50 T PyInit_hello_wrap 3 U PyInstanceMethod_New 4-- 50000000000004dc0 T wrap_hello() 6 U hello(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) 7 U operator delete(void*)@@GLIBCXX_3.4
試したこと
リンクオプションにlibhello.aの指定を追加
※yymmtさんの指摘により共有ライブラリのPrefixをPYBIND11_MODULEの第一引数に合わせました
bash
1g++ -O3 -Wall -shared -std=c++11 -fPIC -L ../lib -lhello `python3 -m pybind11 --includes` wrapper.cpp -o hello_wrap`python3-config --extension-suffix`
補足情報(FW/ツールのバージョンなど)
Ubuntu 18.04
python 3.7.3
g++ 7.5.0
あなたの回答
tips
プレビュー