向 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 的函数的外部定义的主要内容,如果未能解决你的问题,请参考以下文章

Python ctypes 模块

Python 外部函数调用库ctypes简介

向量化数学函数的免费/开源 C/C++ 库? [关闭]

Python调用DLL动态链接库——ctypes使用

python 和 ctypes 访问具有嵌套结构的 c++ 类

使用 ctypes 在 python 中使用 C++ 库