C.GoString()仅返回首字符:Python调用Go c-shared库字符串传参异常
问题原因
Python3 的 ctypes 库做跨语言调用时,默认会将 Python 原生的 str 类型转换为宽字符指针 c_wchar_p,每个字符占用2字节(小端序存储下ASCII字符的高位为0值)。而Go侧定义的入参是单字节的C字符串指针 *C.char,读取字符串时会以第一个0值作为结束标识,因此只能识别到第一个有效字符。
解决方案
你只需要在Python侧显式指定函数的参数类型,并将传入的字符串编码为UTF-8字节格式即可:
import ctypes from ctypes import cdll, c_char_p, c_void_p website = "https://draftss.com" domain = "draftss.com" website_ip = "23.xxx.xxx.xxx" website_tech_finder_lib = cdll.LoadLibrary("website_tech_finder/builds/websiteTechFinder.so") # 1. 显式声明函数的参数类型和返回值类型 website_tech_finder_lib.FetchAllData.argtypes = [c_char_p, c_char_p, c_char_p] website_tech_finder_lib.FetchAllData.restype = c_char_p # 2. 字符串编码为utf-8字节后传入 result_json_bytes = website_tech_finder_lib.FetchAllData( website.encode('utf-8'), domain.encode('utf-8'), website_ip.encode('utf-8') ) # 将返回的C字节串转为Python字符串 result_json_string = result_json_bytes.decode('utf-8')
额外注意事项
- Go侧通过
C.CString创建的返回值字符串内存不属于Go的GC管理范围,你需要额外导出一个释放内存的Go函数,在Python侧使用完返回值后调用释放,避免内存泄漏:
Python侧使用完返回值后调用://export FreeMemory func FreeMemory(p *C.char) { C.free(unsafe.Pointer(p)) }website_tech_finder_lib.FreeMemory.argtypes = [c_void_p] website_tech_finder_lib.FreeMemory(result_json_bytes)
内容的提问来源于stack exchange,提问作者Arun Nair
相关产品推荐
相关产品推荐

