一、背景
因为密码学有很多较快的算法是基于c或c++纂修,而工程上主要以go语言为主,所以在此梳理一些go调用c常见问题和用例。
有很多奇特的方式进行传输,但是想要性能最优还是以指针传输作为主要传输方式。
一些简单的计算可以直接使用c编写成.h进行引用,但在工程部署常常拥有大量依赖库,若在服务器上部署时间太慢,还可能存在网络问题。所以最佳方式是将所有依赖库编译成动态库.so和.dylib供部署方使用。
二、cgo调用
1.cgo依赖库调用需要建设环境:
| CGO_LDFLAGS |
-L/Users/admin/Desktop/pir/pir_arm64/pir_cpp/cmake_arm -lpir |
-L{path} -l{动态库}:比如libpir.so |
| DYLD_LIBRARY_PATH |
/Users/admin/Desktop/pir/pir_arm64/pir_cpp/cmake_arm |
动态库位置 |
| CGO_CFLAGS |
-I/Users/admin/Desktop/pir/pir_arm64/pir_cpp/thirdparty/pir |
.h头文件位置 |
可以在环境中export全局设置,也可以启用之前单次引入:
CGO_CFLAGS="-I${PIR_HOME}/pir_cpp/thirdparty/pir"
DYLD_LIBRARY_PATH="${PIR_HOME}/pir_cpp/build"
CGO_LDFLAGS="-L${PIR_HOME}/pir_cpp/build -lpir" go run main.go
注意:同时饮用两个依赖库:
CGO_ENABLED=1 CGO_CFLAGS="-I${PIR_HOME}/pir_cpp/thirdparty/pir -I${GMSSL_HOME}/include"
CGO_LDFLAGS="-L${PIR_HOME}/pir_cpp/build -lpir2
-L${GMSSL_HOME}/lib -lgmcrypto -lgmssl"
go build -tags=jsoniter -ldflags "$(API_LINK_OPTIONS)" -o ${BIN_PATH}/${API_APP_NAME} ${API_CMD_PATH}
在Goland中配置全景变量CGO_LDFLAGS时不要加双引号。
2.go如何调用c函数并获得计算结果(方法很多,介绍最为稳定,速度最快的方案)
(1)数据结构简单:
func OprfBlind(id []byte, key []byte) ([]byte, error) {
if len(key_receiver) != 32 {
return nil, ErrInvalidKey
}
if id_receiver == nil {
return nil, ErrEmptyParameter
}
size := C.size_t(32)
array := C.malloc(size)
defer C.free(array)
C.oprf_mul_value((*C.char)(unsafe.Pointer(&id[0])), (*C.ch

本文介绍了在Go语言工程中调用C代码的常见问题和最佳实践,包括设置环境变量、调用C函数获取计算结果的方法,以及处理内存分配和循环中的注意事项。提供了一个简单的cgo调用示例,展示了如何交换字符数组和结构体内容。
最低0.47元/天 解锁文章
2289

被折叠的 条评论
为什么被折叠?



