向 C/C++ 库提供具有 ctypes 的函数的外部定义
Posted
技术标签:
【中文标题】向 C/C++ 库提供具有 ctypes 的函数的外部定义【英文标题】:Provide external definition of function with ctypes to a C/C++ library 【发布时间】:2013-12-12 17:55:11 【问题描述】:我有一个使用函数的简单库 hello_printf(const char *format, ...) 在其 API 之一中。使用时 这个库在 C 中,我将 hello_printf 的函数指针指向 使用库和代码在外部应用程序中的 printf 可以无缝工作。
hello_printf 不是 API,而是用于实现一个 API 的。这样做的原因是我想要外部应用程序 使用库提供 printf 的实现(外部绑定)。
现在我想在 python 中使用这个库,并且我正在使用 ctypes 来调用 API,但是我无法找到一种方法来找到函数与 ctypes 的提供外部绑定。 即将 hello_printf() 指向 libc 的 printf,这样“hello_printf = libc.printf”。
【问题讨论】:
这在 ***.com/questions/16513708/… 和 ***.com/questions/544173/… 中几乎涵盖了,为了完整性而提及。 【参考方案1】:您正在寻找 ctypes 数据类型的 in_dll
方法。
C:
#include <stdlib.h>
int (*hello_printf)(const char *format, ...) = NULL;
int test(const char *str, int n)
if (hello_printf == NULL)
return -1;
hello_printf(str, n);
return 0;
ctypes:
from ctypes import *
cglobals = CDLL(None)
lib = CDLL("./lib.so")
hello_printf = c_void_p.in_dll(lib, "hello_printf")
hello_printf.value = cast(cglobals.printf, c_void_p).value
>>> lib.test("spam %d\n", 1)
spam 1
0
【讨论】:
谢谢。该解决方案有效。非常感激。这个解决方案只有一个小问题。 hello_printf 函数被解析为“lib.so”并且完美运行。就我而言,lib.so 还通过 dlopen 打开另一个动态库,即 lib_runtime.so,它也使用 hello_printf。有什么方法可以将新函数暴露给使用 lib.so 而不是从 python ctypes 调用的其他库。 你的意思是像将标志RTLD_GLOBAL
传递给dlopen
,即lib = CDLL('./lib.so', RTLD_GLOBAL)
? Linux 上的默认值为 RTLD_LOCAL
。
非常感谢。你说的对。我只是使用默认模式,因此其他库没有得到解决。它工作完美。再次感谢您的帮助。以上是关于向 C/C++ 库提供具有 ctypes 的函数的外部定义的主要内容,如果未能解决你的问题,请参考以下文章