Python 是否允许定义共享库可以直接调用的 C 函数?

问题描述 投票:0回答:1

我想出了如何让 Python 从我的共享库调用函数:

import ctypes

def bar():
    return 1337

dll = ctypes.PyDLL("./mod.so")

assert dll.foo(ctypes.c_float(42)) == 42 + 1337

其中

mod.so
可以像 C:
 中那样调用 
bar

Python 函数
int foo(float f) {
    PyObject *module = PyImport_ImportModule("main");
    PyObject *bar = PyObject_GetAttrString(module, "bar");
    PyObject *args = PyTuple_Pack(0);
    PyObject *result = PyObject_CallObject(bar, args);
    return f + PyLong_AsInt(result);
}

我本质上是在寻找一种方法让 C

foo()
函数直接调用 Python 代码中的函数,而不需要像
PyObject_CallObject()
这样的 Python 特定内容。这就是我试图将 C 文件变成:

int foo(float f) {
    return f + bar();
}

背景

这很好,但是我的编程语言(参见我的博客文章)其编译器+链接器输出一个通用的

mod.so
,应该可以由任何编程语言使用,所以不仅仅是Python。

这个

mod.so
对于 C 和 C++ 来说是开箱即用的,因为共享库只是使用
call
指令来调用主可执行文件的
bar
函数。另一方面,Python(以及大多数其他高级语言)不允许您直接调用这样的 Python 函数。这是有道理的,因为 Python 将原始 C 类型包装在自定义结构中。这就是为什么我们需要在上面的代码中调用
PyObject_CallObject()

可以编写一个程序,用

call
+
PyImport_ImportModule()
+ 等调用链替换所有
PyObject_GetAttrString()
指令,但出于技术原因,我更愿意单独保留
mod.so

我所做的工作是在 Python 代码和

adapter.c
之间放置一个
mod.so
作为中间人。
adapter.so
的存在只是为了公开
bar
可以直接调用的
mod.so
包装函数,其中包含
PyObject_CallObject
和 co。来电。有关粗略代码,请参阅我之前的 Stack Overflow 问题

因为我的编程语言已经要求游戏开发者在

mod_api.json
中记录mod API,所以可以自动重新生成这个
adapter.c
文件,但理想情况下根本不需要这一步。

循环回到帖子标题

Python 是否允许定义共享库可以直接调用的 C 函数?如果是这样,那么我就不必担心修改

mod.so
或拥有
adapter.c
。谢谢。

python c shared-libraries
1个回答
0
投票

我输入了此内容,然后向上滚动,发现您可能已经回答了自己的问题。 我能够从 docs.python.org 上的 Python 文档中检索“ctypes”(Python 的外部函数库)的此信息。 它基本上允许您调用 dll 或共享库中的函数。 源代码位于 docs.python.org/3/library/ctypes 的 Lib/ctypes。

© www.soinside.com 2019 - 2024. All rights reserved.