使用ctypes将C的char*转换为Python bytes时返回整数的解决方法
问题根因
ctypes加载C函数时,默认将所有函数的返回值按C的int类型解析,你拿到的数值278419308本质是hello()返回的字符串常量的内存地址,不是字符串内容本身。
另外你贴的C代码存在语法错误:return "hello"行尾缺少分号,编译阶段就会报错。
修正步骤
- 先修正C代码语法,编译为对应平台的动态库:
Windows平台编译时需要给导出函数加__declspec(dllexport)声明,否则动态库不会导出该函数符号;Linux/macOS不需要额外导出声明。
修正后的C代码示例:// Windows环境下将函数头改为: __declspec(dllexport) char* hello() { char* hello() { return "hello"; } - Python侧调用前,显式声明
hello函数的返回值类型为c_char_p(对应C的char*类型),ctypes会自动将该类型返回值转为Python的bytes对象。
修正后的Python代码:import ctypes # 替换为你自己编译的动态库实际路径 my_c = ctypes.CDLL("./myclib.dll") # Windows路径示例 # my_c = ctypes.CDLL("./libmyclib.so") # Linux路径示例 # my_c = ctypes.CDLL("./libmyclib.dylib") # macOS路径示例 # 显式指定返回值类型为char* my_c.hello.restype = ctypes.c_char_p result = my_c.hello() print(result) # 直接获取bytes类型结果:b'hello' # 需要Python字符串类型时做编码转换即可 print(result.decode("utf-8")) # 输出字符串:hello
注意事项
- 当前示例返回的是字符串常量,存储在进程的只读数据段,不需要手动释放内存;如果返回的是堆上动态分配的
char*,必须在C侧实现对应的内存释放接口,避免内存泄漏。 - 不要随意将返回
char*的函数返回类型设为c_void_p,该类型会返回整数形式的内存地址,需要额外做指针转换才能拿到字符串内容,增加不必要的代码复杂度。
内容的提问来源于stack exchange,提问作者klg
相关产品推荐
相关产品推荐

