CFFI无法找到函数,即使它们在库中

2024-04-26 10:17:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试使用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 )

但是我得到了这个错误:

在用户名@Ubuntu1204VB:~/tests/cffi_tests/structure$python主.py
回溯(最近一次呼叫):
“文件”主.py“,第22行,in
结构=lib.CreateStructure库()
文件“/usr/local/lib/python2.7/dist-packages/cffi/api.py文件“,第810行,在“生成访问器(名称)”中
文件“/usr/local/lib/python2.7/dist-packages/cffi/api.py文件“,第806行,在make\u accessor accessors[name](name)中
文件“/usr/local/lib/python2.7/dist-packages/cffi/api.py文件“,第751行,在accessor_函数raise AttributeError(“%s:%s%”(name,e))
AttributeError:CreateStructure:“在库中找不到函数'CreateStructure'。/lib”/libstructure.so文件':./lib/libstructure.so文件:未定义符号:CreateStructure”

所以,我检查了里面的东西。/lib/libstructure.so文件,使用nm-DC:

@Ubuntu1204VB:~/tests/cffi_tests/structure$nm-DC./lib/libstructure.so文件
................................ 注册类别
0000000000000731吨自由结构(结构*)
0000000000000702 T打印结构(结构*)
00000000000006bc T CreateStructure()
000000000020201028启动
................................ 最终确定
................................ 开始时
00000000002018A数据
0000000000201040结束
0000000788吨 0000000000000588 T\u初始化
................................ 免费
................................ U malloc
................................ U打印

CreateStructure似乎就在那里。

所以我创建了一个C main来测试这个库,它成功了。但是,我必须包含库和我用来创建共享库(./src)的源代码的头(./include/structure.h)/结构.cpp). 在

然后,我将头复制并粘贴到用于创建共享库的源代码中,因为我无法在Python代码中找到将其与库一起加载的方法,然后重新构建了共享库。不幸的是,我在执行python时仍然遇到相同的错误。这意味着问题不是来自可能丢失的头文件。在

因此,我想知道在使用外国金融机构(/lib“/libstructure.so文件“),以确保它们正确加载。。。或者不是。在

有办法吗?我在这里遗漏了什么?在

编辑:调查
我在源代码中添加了以下函数:

^{pr2}$

和“intmain(void)”在外国金融机构,超过CreateStructure的原型。
当我只打电话的时候主库()... 它打印了42。。。如果我更改int test(void)的intmain(void)并调用lib.测试(),它给我错误“undefined symbol:test”…
如果我将其他函数的名称改为“main”(一次一个),它们可以正常工作。好像cffi只能使用名为“main”的函数。。。在

编辑:回复评论
我在simple-example/中使用make得到以下错误:

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  

请注意,我使用的是Ubuntu12.04,我刚刚使用sudo apt get install clang安装了clang。在

另外,下面是我用来编译共享库的makefile:

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}

Tags: 文件函数pyaddsoexamplelibusr
1条回答
网友
1楼 · 发布于 2024-04-26 10:17:23

解决方法如下:

Armin Rigo指出,{{CD1}}显示代码是通过C++来编译的,通过显示函数如^ {CD2>}而不是从C标准库中的函数,如^ {< CD3>}(注意括号存在,因为C++依赖于名字的参数,C不允许多个函数同名)。在

因此,要用C编译,源文件的名称必须从structure.cpp更改为structure.c,因为文件扩展名与GCC有关。在

相关问题 更多 >