cgo调用,高效快速稳定,无内存碰撞

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

一、背景

因为密码学有很多较快的算法是基于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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值