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

Python3.7调用C++动态库遇OSError内存访问违规问题求助

解决Python调用C++共享库时的访问违规问题

问题原因

  • 参数不匹配:main函数要求两个参数int argc和char* argv[],你调用时只传了一个字符串,导致argc被赋予随机值,argv[1]访问非法内存,触发访问违规。
  • C++名字修饰:C++编译器会对函数名进行修饰(比如main会变成类似_Z4mainiPPc的符号),ctypes无法直接通过main找到正确的函数入口。
  • 字符串类型不兼容:Python默认字符串是Unicode,直接传递会和C的char*类型不匹配,需要转换为字节串。

解决方案

推荐不要用main作为共享库导出函数,而是编写专门的导出函数并禁用C++名字修饰,具体步骤如下:

1. 修改C++代码

编写专用的导出函数,用extern "C"避免名字修饰:

#include <iostream>

extern "C" {
    // 定义简单的导出函数,接收const char*类型参数
    void say_hello(const char* name) {
        std::cout << "hello," << name << std::endl;
    }
}

2. 编译共享库

执行编译命令生成共享库:

g++ -shared -Wl,-soname,hello -o hello.so -fPIC hello.cpp

3. Python调用代码

正确传递字节串参数,并指定函数参数类型:

import ctypes as C

# 加载共享库
so = C.cdll.LoadLibrary("./hello.so")

# 明确指定函数的参数类型,避免类型不匹配
so.say_hello.argtypes = [C.c_char_p]

# 传递字节串(对应C的const char*)
so.say_hello(b"world")

若坚持调用main函数(不推荐)

如果一定要调用main,需要严格匹配参数类型和数量:

import ctypes as C
from ctypes import POINTER

so = C.cdll.LoadLibrary("./hello.so")

# 声明main函数的参数类型和返回值
so.main.argtypes = [C.c_int, POINTER(C.c_char_p)]
so.main.restype = C.c_int

# 构造argv数组:第一个元素是程序名(可随意填写),第二个是你的参数
argv = (C.c_char_p * 2)()
argv[0] = b"hello"
argv[1] = b"world"

# 调用main,传入argc=2和构造好的argv
so.main(2, argv)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 23:35:26