# cgo-demo **Repository Path**: deng-yongsheng/cgo-demo ## Basic Information - **Project Name**: cgo-demo - **Description**: go调用c++代码demo - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-10-18 - **Last Updated**: 2022-10-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CGo调用C++ ## 将C++代码编译成dll(或静态库) ```c++ extern "C" __declspec(dllexport) InferResult *Infer(const char*); extern "C" __declspec(dllexport) void DeleteInferResult(InferResult*); ``` **注意:** 1. C++默认生成的符号会添加前缀`_`(下划线),以支持函数重载。所以需要添加`extern C`声明,生成C语言符号。 2. 添加`__declspec(dllexport)`,将符号添加到`dll`。也可以将符号名写入`.def`文件,效果是一样的。 3. 添加`.def`文件,否则visual studio可能不生成`.lib`文件。 4. 使用mingw中的`dlltool`工具将`.lib`文件转换为`.a`文件,否则cgo无法支持。 `dlltool`工具转换`.lib`到`.a` ```cmd dlltool --dllname dll --output-lib dll.a ``` ## 在Go语言中引用dll ```go //#cgo CFLAGS: -I${SRCDIR}/lib //#cgo LDFLAGS: -L${SRCDIR}/lib -ldll-test //#include "dll-test.h" import "C" ``` **注意:** 1. `${SRCDIR}`环境变量代表当前代码的路径,避免绝对引用导致编译问题。 2. 在C语言中申请的空间,使用C语言内的函数进行释放,尽量避免内存泄露。 3. 确保`dll`文件在`.a`文件的同一目录下,否则无法通过编译。 4. 确保`dll`文件在cgo项目的运行目录,否则go项目启动后直接崩溃。 ## CGo中的各种类型转换 ### 数值类型转换 ```go // C整数转go整数 int(C.int) ``` ### 字符串转换 ```go // go字符串转c字符串 C.CString(string) // C字符串转go字符串 C.GoString(*C.char) ``` ### C指针转Go切片 ```go // 某类型指针转换为指定长度和容量的切片 slice := unsafe.Slice(* C.type, size int) ``` ### 枚举转换 ```go // 枚举转换映射表 var InferResultErrMap = map[C.int]error{ C.OK: nil, C.InputImageErr: errors.New("输入图片异常"), C.EngineFileErr: errors.New("engine文件异常"), C.InferErr: errors.New("推理过程发生错误"), } ```