CGO是C语言和Go语言之间的桥梁,所以GO是没有办法直接使用CPP的类的。

我们可以通过增加一族C语言函数接口作为CPP类和CGO之前的桥梁的,这样

就可以实现C和Go之间的互联。

  • my_buffer.h cpp代码内容,定义一个class。
//
// Created by fly on 19-11-8.
//
#include <string> #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<MyBuffer*>(p);
}
char* MyBuffer_Data(handle p) {
return static_cast<MyBuffer*>(p)->Data();
}
int MyBuffer_Size(handle p) {
return static_cast<MyBuffer*>(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 <stdio.h>
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 失败
  • 打包命令  go build 会自动根据 #include "my_buffer_capi.h" 找到C库并进行打包
  • 实例代码

Go调用cpp类的更多相关文章

  1. [转]C#调用C++类(以COM组件的形式)

    如果想用C#调用C/C++写的函数,可以先将C/C++的函数写成dll文件,由C#用DllImport的方式来调用,但是这种方法无法调用C++写的类,如果想调用C++类,可以先把C++类封装成COM组 ...

  2. CPP/类/成员函数访问权限2

    // main.cpp // OOL // Created by mac on 2019/4/4. // Copyright © 2019年 mac. All rights reserved. // ...

  3. MFC 添加C++类,别的类不通过C++类的定义的对象就可以直接调用C++类里面的成员函数;

    MFC 添加C++类,不用定义C++类的对象,别的类不通过C++类的定义的对象就可以直接调用C++类里面的成员函数: 1先在mfc程序中添加普通类CProdata,然后删除头文件Prodata.h里面 ...

  4. 29.qt quick-在QML中调用C++类

    1.Qml调用C++类 Qt QML模块提供了一组API,用来将C++类扩展QML中.您可以编写扩展来添加自己的QML类型,扩展现有的Qt类型,或调用无法从普通QML代码访问的C/C++函数本章将学习 ...

  5. oracle调用JAVA类的方法

    导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了,  1.操作系统需要拥有支持loadjava命令的jdk.  2.加 ...

  6. Java中是否可以调用一个类中的main方法?

    前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...

  7. 规则引擎集成接口(七)规则引擎调用Java类

    规则引擎调用Java类 通过myEclipse编写一个简单工程,其中方法是两数相加等到结果,既结果1=输入值1+输入值2.实现规则调用外部接口的方法有三种. 1:接口实例:在myEclipse中制作一 ...

  8. java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊

    java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...

  9. C#-面向对象——如何调用使用类 普通方法、静态方法的使用

    类的调用使用 新建的类的命名空间与主函数的命名空间默认相同,如果不同,则主函数无法调用自定义类 比如: 只需要进行引用即可 如果不知道方法的类名,可以右键鼠标 → 解析 → using 即可 普通方法 ...

随机推荐

  1. linux 装composer的出现的问题

    curl -sS https://getcomposer.org/installer | php php 值得是php的liux下的安装目录 php环境变量 当装compser 的时候,出现      ...

  2. Go中使用seed得到相同随机数的问题

    1. 重复的随机数 废话不多说,首先我们来看使用seed的一个很神奇的现象. func main() { for i := 0; i < 5; i++ { rand.Seed(time.Now( ...

  3. Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

    多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程. 一.ThreadPoolTaskExecutor ...

  4. PCIE DMA实现

    基于Spartan-6, Virtex-5/Virtex-6/Virtex-7/7 Series FPGA PCI Express Block Endpoint模块设计PCI Express Endp ...

  5. 有了这套模板,女朋友再也不用担心我刷不动 LeetCode 了

    全文包含 12000+ 字.30 张高清图片,预计阅读时间为 40 分钟,强烈建议先收藏再仔细阅读. 作者 | 李威 整理 | 公众号:五分钟学算法 个人博客 | https://www.cxyxia ...

  6. C语言函数名以及取地址的区别和联系

    有时看到如下的代码: /*****************************/ #include <stdio.h> #include <string.h> #inclu ...

  7. python-setup模块

    本地打包,setup安装 一.distutils 使用:distutils 进行打包,步骤如下,以单一文件为例. 1.创建文件 在同一目录下.写一个foo.py文件: #-*- coding:utf- ...

  8. Java8新特性之空指针异常的克星Optional类

    Java8新特性系列我们已经介绍了Stream.Lambda表达式.DateTime日期时间处理,最后以"NullPointerException" 的克星Optional类的讲解 ...

  9. 全球首个开放应用模型 OAM 开源 | 云原生生态周报 Vol. 23

    作者 | 临石.元毅.冬岛.衷源.天元 业界要闻 全球首个开放应用模型 OAM 开源 2019 年 10 月 17 日,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟(花名:小邪)在 Qcon ...

  10. TCP Traffic Analyzer

    TCP Traffic Analyzer 工具yahoo 发布的一款开源网络分析工具,可以分析网络应用在服务器端与客户端之间的运行状态Yconalyzer保持与tcpdump兼容,两者生成的抓取文件能 ...