You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python是否支持定义可被共享库直接调用的C函数?

Python能否定义可被共享库直接调用的C函数?

可以实现,通过Python的C扩展机制,将Python函数包装为符合C调用约定的导出函数,让共享库直接调用该包装函数即可。

实现原理

Python函数本质是虚拟机字节码,无法直接被C的call指令调用。我们需要编写一个C风格的包装函数,内部通过Python C API调用目标Python函数,再将这个包装函数导出为共享库符号,让你的mod.so可以直接链接调用。

具体实现步骤

1. 编写C扩展包装代码

创建wrapper.c,将Python的bar()包装为符合C ABI的导出函数:

#include <Python.h>

// 全局保存Python的bar函数对象,避免重复查找
static PyObject* py_bar_func = NULL;

// 供mod.so直接调用的C风格函数
int bar() {
    // 首次调用时获取Python中的bar函数
    if (!py_bar_func) {
        PyObject* main_module = PyImport_ImportModule("main");
        py_bar_func = PyObject_GetAttrString(main_module, "bar");
        Py_XDECREF(main_module); // 释放模块引用
    }

    // 调用Python函数并转换返回值
    PyObject* result = PyObject_CallObject(py_bar_func, NULL);
    int ret_val = PyLong_AsInt(result);
    Py_XDECREF(result); // 释放结果引用
    return ret_val;
}

// Python模块初始化(必须存在)
static struct PyModuleDef wrapper_module = {
    PyModuleDef_HEAD_INIT,
    "wrapper",
    NULL,
    -1,
    NULL
};

PyMODINIT_FUNC PyInit_wrapper(void) {
    return PyModule_Create(&wrapper_module);
}

2. 编译C扩展为共享库

用gcc编译成wrapper.so(替换python3.x为你的Python版本):

gcc -shared -fPIC -I/usr/include/python3.x wrapper.c -o wrapper.so -lpython3.x

3. 修改Python代码加载扩展与共享库

确保wrapper.so的符号全局可见,让mod.so能解析到bar函数:

import ctypes
import sys

def bar():
    return 1337

# 加载自定义C扩展,初始化Python函数引用
sys.path.insert(0, '.')
import wrapper

# 加载wrapper.so并设置符号全局可见,让mod.so能找到bar
wrapper_dll = ctypes.CDLL("./wrapper.so", mode=ctypes.RTLD_GLOBAL)

# 加载mod.so,此时它可以直接调用bar()
dll = ctypes.PyDLL("./mod.so")

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

4. 简化mod.so的C代码

现在mod.so的代码可以直接写成你想要的形式:

// 声明外部的bar函数
int bar();

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

关键注意事项

  • 符号可见性:必须用RTLD_GLOBAL加载wrapper.so,否则mod.so无法解析bar符号。
  • 引用计数管理:在C扩展中要正确处理Python对象的引用计数,避免内存泄漏。
  • 自动生成:结合你已有的mod_api.json,可以编写脚本自动生成wrapper.c的包装函数代码,完全省去手动编写的步骤。

内容的提问来源于stack exchange,提问作者MyNameIsTrez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:01:17