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. 3D漫游的分类 3D Navigation Taxonomy

    在2001年CHI发表的论文中1,Tan等人提出了一种对3D漫游的分类方法. 当时关于3D漫游(3D Navigation)的研究主要分为两种:一种是发掘有关漫游的认知原则,一种是开发一些具体的漫游技 ...

  2. js中对于数组的操作

    let myArray=[11,22,33]; console.log('原数组:',myArray); myArray.push(44,55); console.log('用push在数组后面插入元 ...

  3. Mybatis-Plus学习.,简化你的开发,提升开发效率.

    Mybatis-Plus学习以及实践 简介 参考网址 开发环境 开始开发 - 配置pom.xml - Dao/Service/Entity - 基本方法 - 查询类 - 更新类 分页插件 - pom. ...

  4. 响应系统设置的事件(Configuration类)

    1.Configuration给我们提供的方法列表 densityDpi:屏幕密度 fontScale:当前用户设置的字体的缩放因子 hardKeyboardHidden:判断硬键盘是否可见,有两个可 ...

  5. javascript随机点名--案例

    主要知识点涉及if选择结构判断语句.数组的定义.定时器.清除定时器.日期对象的使用. 1.HTML结构 <!DOCTYPE html> <html> <head> ...

  6. Linux入门(服务)

    LInux入门之 服务 服务介绍 常驻在内存中的程序,且可以提供一些系统或网络功能,那就是服务.比如: apache提供web服务 ftp提供文件下载上传服务 ssh提供了远程连接服务 防火墙提供了安 ...

  7. Linux内核版本介绍与查询

    Linux内核版本命名在不同时期有着不同的规范,在涉及到Linux版本问题时经常容易混淆,主线版本/稳定版/长期支持版本经常搞不清楚,本文主要记录下内核版本命名的规则以及如何查看Linux系统版本信息 ...

  8. GO 第一个程序Hello world

    第一个程序:HelloWorld 一.go项目工程结构 配置好工作目录后,就可以编码开发了,在这之前,我们看下go的通用项目结构,这里的结构主要是源代码相应地资源文件存放目录结构. 1.1 gopat ...

  9. Flask中的cookie和session

    from flask import Flask app = Flask(__name__) 一.cookie from flask import Flask, make_response, reque ...

  10. 介绍ArcGIS中各种数据的打开方法——shp(矢量文件)

    2.加载shp文件到地图控件 ShapeFile是一种矢量数据模型的计算机数据组织文件,用于在计算机上表达矢量数据的计算机文件. 加载ShapeFile文件最主要是:axMapControll控件对象 ...