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

Linux下导入含ctypes加载.so的.py文件时出现PyInit_a错误

解决import普通动态库时出现“dynamic module does not define module export function (PyInit_a)”的问题

错误原因

Python在导入后缀为.so的文件时,默认会将其识别为Python C扩展模块,这类模块必须导出PyInit_<模块名>(Python3)或init<模块名>(Python2)初始化函数。但你的a.so是普通的C兼容动态库,没有实现该导出函数,因此触发报错。

解决方案

方案1:修改动态库文件名(最简单)

将编译生成的动态库改名,避免与Python模块名冲突:

  • 编译命令调整为:
    g++ -shared -fPIC -o liba.so a.cpp
    
  • 修改a.py中的加载路径:
    import ctypes
    lib = ctypes.cdll.LoadLibrary('./liba.so')
    # 调用函数f
    lib.f()
    
  • 此时b.py中执行import a会正确导入a.py文件,而非同名的.so库,问题解决。

方案2:调整Python模块的导入逻辑

如果不想修改动态库名称,可通过以下方式避免Python误加载.so文件:

  • 在a.py中明确指定动态库的绝对加载路径,确保加载的是正确的文件:
    import ctypes
    import os
    # 获取当前脚本所在目录
    lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'a.so')
    lib = ctypes.cdll.LoadLibrary(lib_path)
    
  • 若b.py与a.py、a.so同级,可通过调整sys.path优先导入Python文件:
    # b.py中
    import sys
    sys.path.insert(0, './')  # 确保当前目录优先导入Python模块
    import a
    

方案3:将动态库封装为标准Python扩展模块

如果需要更规范的Python模块调用方式,可将普通动态库改造为Python C扩展:

  1. 安装Python开发依赖(以Debian/Ubuntu为例):
    sudo apt-get install python3-dev
    
  2. 修改a.cpp,添加Python扩展的初始化代码:
    #include <Python.h>
    
    extern "C" {
        // 原有的函数f
        void f() {
            // 你的函数实现
        }
    
        // 定义模块方法列表
        static PyMethodDef AModuleMethods[] = {
            {"f", (PyCFunction)f, METH_NOARGS, "Execute function f"},
            {NULL, NULL, 0, NULL}  // 方法列表结束标记
        };
    
        // 定义模块结构体
        static struct PyModuleDef AModuleDef = {
            PyModuleDef_HEAD_INIT,
            "a",          // 模块名
            "A sample module",  // 模块文档
            -1,           // 模块状态大小(-1表示全局状态)
            AModuleMethods
        };
    
        // 模块初始化函数(必须导出)
        PyMODINIT_FUNC PyInit_a(void) {
            return PyModule_Create(&AModuleDef);
        }
    }
    
  3. 使用Python提供的编译参数编译:
    g++ -shared -fPIC -o a.so $(python3-config --cflags --ldflags) a.cpp
    
  4. 此时b.py中可直接导入并调用:
    import a
    a.f()
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:12:41