即使它们在库中,CFFI也找不到函数
我想使用CFFI加载共享库。该代码旨在实例化C结构,打印并销毁它。即使它们在库中,CFFI也找不到函数
#!/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)
但我收到此错误:
用户名@ Ubuntu1204VB:〜/测试/ cffi_tests /结构$蟒蛇main.py
回溯(最近通话最后一个):
文件“main.py”,第22行,在
structure = lib.CreateStructure()
文件“/usr/local/lib/python2.7/dist-packages/cffi/api.py”,第810行,在__getattr__ make_accessor(名称)
文件“/usr/local/lib/python2.7/dist-packages/cffi/api.py”,行806,在make_accessor访问器[名称](名称)
文件“/ usr/local/lib/python2。 7/dist-packages/cffi/api.py“,第751行,在accessor_function raise AttributeError('%s:%s'%(name,e))
AttributeError:CreateStructure:”function'CreateStructure' './lib/libstructure.so':./lib/libstructure.so:未定义的符号:CreateStructure”
所以,我检查了里面是什么./lib/libstructure.so,使用纳米-DC:
@ Ubuntu1204VB:〜/ tests/cffi_tests/structure $ nm -DC ./lib/libstruc ture.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 main来测试库,它工作。但是,我必须包含库和用于创建共享库(./src/structure.cpp)的源代码的头文件(./include/structure.h)。
然后,我将头文件复制并粘贴到用于创建共享库的源代码中,因为我无法找到一种方法将它加载到Python代码中的库中,并再次构建共享库。不幸的是,我在执行python时仍然遇到同样的错误。这意味着问题不是来自可能丢失的头文件。
因此,我想知道是否可以在使用ffi.dlopen(“./ lib/libstructure。”)加载它们之后,检查Python代码中的符号。?所以“),以确保正确装载......还是不
没有办法做这样的事情,我在这里失踪
编辑:?调查
我已经添加了以下功能,我的源代码。
int main(void)
{
return printf("%d\n", 42);
}
和 “INT主要(无效)”,在ffi.cdef,在CreateStructure的原型
当我只调用lib.main()......它打印42 ...如果我将int main(void)更改为int test(void)并调用li b.test(),它给我的错误“未定义的符号:测试”...
如果我改变我的其他功能的名称为“主”(一次一个),他们工作正常。这是因为如果CFFI只能消耗功能命名为“主” ......
编辑:答案要评论
我正在使用make
在simple-example/
以下错误:
[email protected]:~/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 [email protected]
./lib/libstructure.so : $(OBJS)
$(CC) $(LDFLAGS) -o [email protected] $^
.PHONY:
clean:
-${RM} ${TARGET_LIB} ${OBJS}
这里是修复:
阿明·里戈指出nm
表明代码被编译成C++,通过显示像CreateStructure()
这样的函数,而不是像C标准库中的printf
这样的函数(注意括号的存在,因为C++依赖于用于名称加密的参数,而C不允许具有相同名称的多个函数)。
因此,要用C编译,必须将源文件的名称从structure.cpp
更改为structure.c
,因为文件扩展名与GCC有关。
这很奇怪。你所做的一切看起来都是正确的......所以如果我不得不猜测,我可能会说它对图书馆和/或cffi的编译有些奇怪,可能呢?尝试查看https://github.com/wolever/python-cffi-example的'how-cffi-works'分支 - 在'simple-example /'目录下运行'make'后,执行'python add-example .py'工作?代码:https://github.com/wolever/python-cffi-example/tree/how-cffi-works/simple-example –
编辑回答你的问题的问题。 – DRz
是的,那么在工具链的某个地方肯定会有一些奇怪的东西。如果你已经安装了gcc,你可以尝试用'CC = gcc'替换'CC = clang',然后运行'make clean;让'看看是否有效。否则我不确定问题是什么,因为'libadd.so'似乎有同样的问题。 –