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 <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]))))
}
- demo源码
https://github.com/tangxiongfei/cgo
注意事项
需要关闭 unset GO111MODULE,不然依赖回去vendor里面找,导致项目go build 失败
打包命令 go build 会自动根据 #include "my_buffer_capi.h" 找到C库并进行打包
- 实例代码
Go调用cpp类的更多相关文章
- [转]C#调用C++类(以COM组件的形式)
如果想用C#调用C/C++写的函数,可以先将C/C++的函数写成dll文件,由C#用DllImport的方式来调用,但是这种方法无法调用C++写的类,如果想调用C++类,可以先把C++类封装成COM组 ...
- CPP/类/成员函数访问权限2
// main.cpp // OOL // Created by mac on 2019/4/4. // Copyright © 2019年 mac. All rights reserved. // ...
- MFC 添加C++类,别的类不通过C++类的定义的对象就可以直接调用C++类里面的成员函数;
MFC 添加C++类,不用定义C++类的对象,别的类不通过C++类的定义的对象就可以直接调用C++类里面的成员函数: 1先在mfc程序中添加普通类CProdata,然后删除头文件Prodata.h里面 ...
- 29.qt quick-在QML中调用C++类
1.Qml调用C++类 Qt QML模块提供了一组API,用来将C++类扩展QML中.您可以编写扩展来添加自己的QML类型,扩展现有的Qt类型,或调用无法从普通QML代码访问的C/C++函数本章将学习 ...
- oracle调用JAVA类的方法
导入jar包 在oracle中导入需要的jar包,我们把编辑好的java类打成jar包,直接在oarcle里面写简单的调用就可以了, 1.操作系统需要拥有支持loadjava命令的jdk. 2.加 ...
- Java中是否可以调用一个类中的main方法?
前几天面试的时候,被问到在Java中是否可以调用一个类中的main方法?回来测试了下,答案是可以!代码如下: main1中调用main2的主方法 package org.fiu.test; impor ...
- 规则引擎集成接口(七)规则引擎调用Java类
规则引擎调用Java类 通过myEclipse编写一个简单工程,其中方法是两数相加等到结果,既结果1=输入值1+输入值2.实现规则调用外部接口的方法有三种. 1:接口实例:在myEclipse中制作一 ...
- java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊
java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...
- C#-面向对象——如何调用使用类 普通方法、静态方法的使用
类的调用使用 新建的类的命名空间与主函数的命名空间默认相同,如果不同,则主函数无法调用自定义类 比如: 只需要进行引用即可 如果不知道方法的类名,可以右键鼠标 → 解析 → using 即可 普通方法 ...
随机推荐
- JS调用activeX实现浏览本地文件夹功能 wekit内核只需要<input type="file" id="files" name="files[]" webkitdirectory/>即可,IE内核比较麻烦
研究了一天,js访问本地文件本身是不可能的,只能借助于插件.植入正题,IE仅支持ActiveX插件. function openDialog() { try { var Message = " ...
- 设计时数据源:在PostgreSql 数据查询中使用参数过滤
在上一篇文章中,我们学习了如何设计时连接PostgreSQL 数据库及环境搭建.本节我们来学习使用PostgreSql 数据源时,创建数据集时带参数过滤的查询语句写法. 在报表中包含两种参数,可参考博 ...
- Nebula Graph 技术总监陈恒:图数据库怎么和深度学习框架进行结合?
引子 Nebula Graph 的技术总监在 09.24 - 09.30 期间同开源中国·高手问答的小伙伴们以「图数据库的设计和实践」为切入点展开讨论,包括:「图数据库的存储设计」.「图数据库的计算设 ...
- B-微积分-Sigmoid函数
目录 Sigmoid函数 一.Sigmoid函数详解 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnbl ...
- Linux上安装jdk1.8和配置环境变量
前言 Linux 上安装jdk1.8 和配置环境变量,参考相关文档,本人在此总结,操作归纳如下. 第一步:创建jdk安装目录(该/usr/local/src 目录是空的,最好把我们自己下载的放到这,容 ...
- navicat for mysql ;连接数据库报错1251,解决办法。
转载 改密码方式:用管理员身份打开cmd mysql -uroot -p(输入密码) 进入mysql执行下面三个命令 use mysql: ALTER USER 'root'@' ...
- MySQL学习(二)索引原理及其背后的数据结构
首先区分几个概念: 聚集索引 主索引和辅助索引(即二级索引) innodb中每个表都有一个聚簇索引(clustered index ),除此之外的表上的每个非聚簇索引都是二级索引,又叫辅助索引(sec ...
- 什么是STM32的ISP?
上一篇笔记分享了STM32的串口IAP实例:STM32串口IAP分享.其中,下载IAP程序时用ISP的方式进行下载.这里的ISP又是什么呢? ISP方式下载程序原理 ISP:In System Pro ...
- Python3的编码整理总结
python3在内存中是用unicode编码方式存储的,所以不能直接储存和传输,要转化为其他编码进行储存和传输. 字符串通过编码转换成字节码,字节码通过解码成为字符串 encode:str --> ...
- 前端工程师如何理解 TCP/IP 传输层协议?
网络协议是每个前端工程师都必须要掌握的知识,TCP/IP 中有两个具有代表性的传输层协议,分别是 TCP 和 UDP,本文将介绍下这两者以及它们之间的区别. TCP/IP网络模型 计算机与网络设备要相 ...