CGO是C语言和Go语言之间的桥梁,所以GO是没有办法直接使用CPP的类的。
我们可以通过增加一族C语言函数接口作为CPP类和CGO之前的桥梁的,这样
就可以实现C和Go之间的互联。
my_buffer.h cpp代码内容,定义一个class。
//
// Created by fly on 19-11-8.
//
#include
#ifndef TORCH_MY_BUFFER_H
#define TORCH_MY_BUFFER_H
class MyBuffer {
std::string* s_;
public:
MyBuffer(int size) {
this->s_ = new std::string(size, char('\0'));
}
~MyBuffer() {
delete this->s_;
}
public:
int Size() const {
return this->s_->size();
}
public:
char* Data() {
return (char*)this->s_->data();
}
};
#endif //TORCH_MY_BUFFER_H
my_buffer_capi.h 声明c函数接口
//
// Created by fly on 19-11-8.
//
#ifndef TORCH_MY_BUFFER_CAPI_H
#define TORCH_MY_BUFFER_CAPI_H
typedef void* handle; // 这里定义一下,然后才能在go里面使用这个数据类型
handle NewMyBuffer(int size);
void DeleteMyBuffer(handle);
char* MyBuffer_Data(handle);
int MyBuffer_Size(handle);
#endif //TORCH_MY_BUFFER_CAPI_H
/*
* class 的声明和定义
*
* // student.h 进行类的声明
*
* class Student {
* Student(std::string name, int age); // 和类名相同的函数就是构造函数
~Student(){} // 析构函数
* void display();
* private:
* int num;
* char name[20];
* char sex;
* }
*
*
* // student.cpp 进行类的定义
*
* #include "student.h"
* void Student::display(){
* count << "num:" <<
* }
*
* Student::Student(std::string name, int age)
* : name_(name),
* age_(age) {}
*
* // main.cpp 进行类的调用
*
* #include
*
* int main() {
* Student stud;
* stud.display();
* return 0;
* }
*
*/
my_buffer_capi.cc 实现c函数接口
//
// Created by fly on 19-11-8.
//
#include "my_buffer.h"
extern "C" {
#include "my_buffer_capi.h"
}
handle NewMyBuffer(int size) {
return new MyBuffer(size);
}
void DeleteMyBuffer(handle p) {
delete static_cast(p);
}
char* MyBuffer_Data(handle p) {
return static_cast(p)->Data();
}
int MyBuffer_Size(handle p) {
return static_cast(p)->Size();
}
my_buffer_capi.go 用go封装函数接口
package main
/*
#cgo CXXFLAGS: -std=c++11
#include "my_buffer_capi.h"
*/
import "C"
import "unsafe"
func cgo_NewMyBuffer(size int) (C.handle) {
p := C.NewMyBuffer(C.int(size))
return p
}
func cgo_DeleteMyBuffer(p C.handle) {
C.DeleteMyBuffer(p)
}
func cgo_MyBuffer_Data(p C.handle) *C.char {
return C.MyBuffer_Data(p)
}
func cgo_MyBuffer_Size(p C.handle) C.int {
return C.MyBuffer_Size(p)
}
type MyBuffer struct {
cptr C.handle
}
func NewMyBuffer(size int) *MyBuffer {
return &MyBuffer{
cptr: cgo_NewMyBuffer(size),
}
}
func (p *MyBuffer) Delete(){
cgo_DeleteMyBuffer(p.cptr)
}
func (p *MyBuffer) Data() []byte {
data := cgo_MyBuffer_Data(p.cptr)
size := cgo_MyBuffer_Size(p.cptr)
return ((*[1 << 31]byte)(unsafe.Pointer(data)))[0:int(size):int(size)]
}
main.go 定义主函数实现调用
package main
//#include
import "C"
import "unsafe"
func main() {
buf := NewMyBuffer(1024)
defer buf.Delete()
copy(buf.Data(), []byte("hello\x00"))
C.puts((*C.char)(unsafe.Pointer(&(buf.Data()[0]))))
}
注意事项
需要关闭 unset GO111MODULE,不然依赖回去vendor里面找,导致项目go build 失败
### 打包命令
```bash
go build 会自动根据 #include "my_buffer_capi.h" 找到C库并进行打包
```