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

将带头文件的C++类编译为so库供Python调用,符号未定义报错如何解决

错误原因

  1. extern "C"使用错误:extern "C"仅能对C风格的函数声明生效,你将包含C命名空间、类定义的头文件包裹在extern "C"块中不会改变类成员函数的编译逻辑,my_class::hello_world还是会被C编译器做名字修饰(Name Mangling),最终导出的符号名是类似_ZN1N8my_class11hello_worldEv的修饰后名称,ctypes按hello_world原名自然找不到对应符号。
  2. ctypes不支持直接调用C++类成员函数:C++类的非静态成员函数隐含this指针参数,调用约定和普通C函数完全不同,就算你找到修饰后的符号名,直接调用也会出现内存错误。

修复方案

步骤1:修改C++实现代码,新增C风格导出接口

不需要修改my_class.h,仅调整my_class.cpp,新增对外暴露的C风格包装函数,显式用extern "C"修饰避免名字修饰,同时封装类的创建、方法调用、销毁逻辑:

// my_class.cpp
#include "my_class.h"
#include <iostream>

using namespace N;
using namespace std;

void my_class::hello_world()
{
    cout << "Hello, World!" << endl;
}

// 对外暴露的C风格接口
extern "C" {
    // 创建my_class实例,返回指针
    void* create_my_class() {
        return new my_class();
    }

    // 调用hello_world方法,传入实例指针
    void my_class_hello_world(void* instance) {
        static_cast<my_class*>(instance)->hello_world();
    }

    // 销毁my_class实例,避免内存泄漏
    void destroy_my_class(void* instance) {
        delete static_cast<my_class*>(instance);
    }
}

步骤2:重新编译生成共享库

编译命令无需调整,直接执行即可:

g++ -fPIC -shared -o my_class.so my_class.cpp

步骤3:修改Python调用代码

通过暴露的C接口完成类操作:

import ctypes

# 加载共享库
lib = ctypes.cdll.LoadLibrary('./my_class.so')
# 创建类实例
instance = lib.create_my_class()
# 调用hello_world方法
lib.my_class_hello_world(instance)
# 销毁实例,释放内存
lib.destroy_my_class(instance)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 11:24:02