CFFI を使用して共有ライブラリをロードしようとしています。このコードは、C 構造体をインスタンス化し、出力して破棄することを目的としています。
#!/usr/bin/env python
from cffi import FFI
ffi = FFI()
ffi.cdef("""
typedef struct
{
int numero;
const char* message;
}STRUCTURE, *PSTRUCTURE;
PSTRUCTURE CreateStructure();
int PrintStructure( PSTRUCTURE );
int FreeStructure( PSTRUCTURE );
""")
lib = ffi.dlopen("./lib/libstructure.so")
structure = lib.CreateStructure()
lib.PrintStructure( structure )
lib.FreeStructure( structure )
しかし、私はこのエラーが発生しています:
username@Ubuntu1204VB:~/tests/cffi_tests/structure$ python main.py
トレースバック (最新の呼び出しが最後):
ファイル "main.py"、22 行目、
構造内 = lib.CreateStructure()
ファイル "/usr/local/lib /python2.7/dist-packages/cffi/api.py"、810 行目、__getattr__ make_accessor(name)
ファイル内"/usr/local/lib/python2.7/dist-packages/cffi/api.py"、行806、make_accessor accessors[name](name)
ファイル "/usr/local/lib/python2.7/dist-packages/cffi/api.py"、751 行、accessor_function で AttributeError('%s: %s' を発生させます% (name, e))
AttributeError: CreateStructure: "関数 'CreateStructure' がライブラリ './lib/libstructure.so' に見つかりません: ./lib/libstructure.so: 未定義のシンボル: CreateStructure"
そこで、nm -DC を使用して、./lib/libstructure.so の内容を確認しました。
@Ubuntu1204VB:~/tests/cffi_tests/structure$ nm -DC ./lib/libstructure.so
......................... ... w _Jv_RegisterClasses
0000000000000731 T FreeStructure(STRUCTURE*)
0000000000000702 T PrintStructure(STRUCTURE*)
00000000000006bc T CreateStructure()
0000000000201028 A __bss_start
................... .... w __cxa_finalize
................................ w __gmon_start__
0000000000201028 A _edata
0000000000201040 A _end
0000000000000788 T _fini
0000000000000588 T _init
................................ U free
......... ................... U malloc
......................... ....... U printf
CreateStructure があるようです。
そのため、ライブラリをテストするために C メインを作成したところ、機能しました。ただし、共有ライブラリ (./src/structure.cpp) を作成するために使用したソース コードのライブラリとヘッダー (./include/structure.h) を含める必要がありました。
次に、共有ライブラリの作成に使用したソース コードにヘッダーをコピー アンド ペーストしました。Python コードでライブラリと共にそれをロードする方法が見つからなかったため、共有ライブラリを再度ビルドしました。残念ながら、Python の実行中に同じエラーが発生します。これは、欠落している可能性のあるヘッダー ファイルが原因で問題が発生していないことを意味します。
したがって、ffi.dlopen("./lib/libstructure.so") を使用してシンボルをロードした後、python コードからシンボルをチェックして、それらが適切にロードされていることを確認できるかどうかを知りたいです...またはいいえ。
これを行う方法はありますか?ここに欠けているものはありますか?
EDIT : 調査
ソース コードに次の関数を追加しました。
int main(void)
{
return printf("%d\n", 42);
}
そして、CreateStructure のプロトタイプに対して、ffi.cdef 内の「int main(void)」。
lib.main()... だけを呼び出すと、42 が出力されます... int main(void) を int test(void) に変更して lib.test() を呼び出すと、「undefined symbol: test」というエラーが表示されます。 「...
他の関数の名前を「main」に(一度に1つずつ)変更すると、正常に動作します。あたかも cffi が「main」という名前の関数しか消費できないかのようです...
EDIT : コメントへの回答in
を使用すると、次のエラーが発生します。 make
simple-example/
username@Ubuntu1204VB:~/tests/python-cffi-example-how-cffi-works/simple-example$ make
clang -shared add.c -o libadd.so
clang -L. -ladd add-example.c -o add-example.exe
/tmp/add-example-r7jvhJ.o: In function \`main': add-example.c:(.text+0x25): undefined reference to `add'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: \*** [add-example.exe] Error 1
私はUbuntu 12.04を使用しており、sudo apt-get install clangを使用してclangをインストールしたばかりであることに注意してください。
また、共有ライブラリのコンパイルに使用したメイクファイルは次のとおりです。
CC = gcc
INC_PATH = -I ./include
DEBUGFLAGS = -g
CFLAGS = -c -fPIC $(DEBUGFLAGS) -Wall -Wextra
LDFLAGS = -fPIC $(DEBUGFLAGS) -Wall -Wextra -shared
OBJS = ./obj/structure.o
TARGET_LIB = ./lib/libstructure.so
RM = rm -f
all: $(OBJS) $(TARGET_LIB)
./obj/structure.o : ./src/structure.cpp
$(CC) $(INC_PATH) $(CFLAGS) $< -o $@
./lib/libstructure.so : $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
.PHONY:
clean:
-${RM} ${TARGET_LIB} ${OBJS}