c语言调用cpp类方法,Go调用cpp类方式一

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库并进行打包

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值