目录
基本操作
1 在go文件中加注释,设置为导出方法,导出C依赖
2 导出so文件(mac或者linux下只需要so)
3 进行调用
报错记录
踩坑1 关于结构体
2 cannot use (_Cfunc_CString)("12345") (value of type *_Ctype_char) as type string in return statement
3 返回值不符合预期
4 [signal SIGSEGV: segmentation violation code
基本操作
主要流程为:
1 在go文件中加注释,设置为导出方法,导出C依赖
比如在Sum这里设置成导出的方法,文件头引入C依赖包
然后进行编译,导出so文件和h文件,使用如下命令进行编译
2 导出so文件(mac或者linux下只需要so)
go build -buildmode=c-shared -o xor.so xor.go
编译后的生成产物
3 进行调用
from ctypes import *
lib = cdll.LoadLibrary('./test.so')
result = lib.Sum(100, 200)
print(result)
报错记录
踩坑1 关于结构体
注意:如果是你要导出的方法有结构体的接收器,编译的时候会报错
比如这情况,编译运行和导出so都会报错
导出so报错
需要注意规避此类方法,转成普通方法
2 cannot use (_Cfunc_CString)("12345") (value of type *_Ctype_char) as type string in return statement
遇到问题比如go中的返回值是string类型的,如果不对go文件对应导出的方法全部修改成对应的C类型会报这个错
比如:
解决
修改go中方法定义的值返回值为C类型,参数对应关系可以参考python调用go或c语言_数据处理专家的技术博客_51CTO博客
编译后调用
3 返回值不符合预期
需要修改python中的代码,增加一行返回值约束
lib.Sum.restype = c_char_p
最后python demo
from ctypes import *
lib = cdll.LoadLibrary('./test.so')
lib.Sum.restype = c_char_p
result = lib.Sum(100, 200)
print(result)
再次调用返回值正常
4 [signal SIGSEGV: segmentation violation code
unexpected fault address 0x10218d000
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10218d000 pc=0x1027afcf8]
场景如下:
这里传参是string类型
报错
解决:
修改参数定义
go中的string对应C中的C.char
编译后调用
from ctypes import *
lib = cdll.LoadLibrary('./test.so')
lib.Sum.argtype = c_char_p
lib.Sum.restype = c_char_p
result = lib.Sum(b"123456")
print(result)
参考:
python调用go或c语言_数据处理专家的技术博客_51CTO博客