go 使用 cgo 调用 C++ 动态库之 封装 C++ 接口
接口封装
假设我们有 test.h
和 test.cpp
我们可以直接使用它们,用 api.h
和 api.cpp
对它们进行封装,向 go 暴露 ==api==。
代码参考如下:
// test.h
#pragma once
#include <iostream>
class Test
{
public:
void sayHello();
};
// test.cpp
#include "test.h"
void Test::sayHello()
{
std::cout << "hello world" << std::endl;
}
注意:extern "C"
,C++ 支持函数重载,C 语言不支持函数重载,函数被 C++ 编译器编译后在库中的名字与C语言的不同,为了解决此类名字匹配的问题,C++ 提供了 C 链接交换指定符号 extern "C"
// api.h
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
void sayHelloWorld();
#ifdef __cplusplus
}
#endif
// api.cpp
#include "api.h"
#include "test.h"
void sayHelloWorld()
{
Test ts;
ts.sayHello();
}
生成动态库
Windows
平台下
g++ --share api.cpp test.cpp -o libapi.dll
go
调用示例
为了方便使用,将 libapi.dll
api.h
放到 main.go
同级,目录参考如下
- api.h
- go.mod
- go.work
- libapi.dll
- main.go
main.go
内容如下
package main
// #cgo LDFLAGS: -L . -lapi -lstdc++
// #cgo CFLAGS: -I ./
// #include "api.h"
import "C"
func main() {
C.sayHelloWorld()
}
编译
go build
go 编译器会自动寻找动态库进行链接。
看看效果
附录
C 语言和 Go 语言的数值类型对应如下