C/C++调用Golang 一
C/C++调用Golang 一
(开发环境:
- 操作系统: windows 7 32位操作系统
- C++: visual studio 2010
- Golang:go version go1.9 windows/386 TDM-GCC-32)
用一个简单的例子演示如何在C++中调用golang程序。用golang编写一个简单的函数,编译成动态链接库,然后在C++中调用该go函数。
第一阶段 将Golang代码编译成动态链接库 (涉及2个文件 main.go和godll.def)
Golang : main.go 一个简单的Add函数
package main
import "C"
//export Add
func Add(a, b int32) int32 {
return a + b
}
func main() {}
为动态链接库指定导出符号,创建godll.def
EXPORTS
Add
将main.go编译成动态链接库,在命令行中执行如下操作:
go build -buildmode=c-archive
go build 生成了两个文件:godll.a godll.h
再执行 gcc -m32 -shared -o godll.dll godll.def godll.a -static -lwinmm -lWs2_32
(需要安装 TDM-GCC-32)
编译后生成 godll.dll
godll.h和godll.dll是C++工程需要的,godll.h的内容如下:
/* Created by "go tool cgo" - DO NOT EDIT. */
/* package _/Y_/godll */
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt32 GoInt;
typedef GoUint32 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_32_bit_pointer_matching_GoInt[sizeof(void*)==32/8 ? 1:-1];
typedef struct { const char *p; GoInt n; } GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern GoInt32 Add(GoInt32 p0, GoInt32 p1);
#ifdef __cplusplus
}
#endif
extern GoInt32 Add(GoInt32 p0, GoInt32 p1); 是导出函数的签名。
用depends22_x86 查看 godll.dll
第二阶段 在C++工程中调用godll.dll
创建名为callgo的vs 2010工程,将godll.h加入到工程,新建main.cpp的源文件:
#include <Windows.h>
#include <stdio.h>
#include "godll.h"
typedef GoInt32 (*funcPtrAdd)(GoInt32 p0, GoInt32 p1);
int main(){
HMODULE h = LoadLibraryA("godll.dll");
if (NULL == h || INVALID_HANDLE_VALUE == h)
{
return -1;
}
funcPtrAdd pfAdd = (funcPtrAdd)GetProcAddress(h,"Add");
if (pfAdd)
{
GoInt32 result = pfAdd(5,4);
printf("Add(5,4) = %d",result);
}
FreeLibrary(h);
return 0;
}
将godll.h中的三行注释掉
//typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
//typedef float _Complex GoComplex64;
//typedef double _Complex GoComplex128;
编译运行,结果如下图:
注意事项:
main.go中 import "C" 这一行一定要有,否则gcc编译时会报符号未定义的错误:
C/C++调用Golang 一的更多相关文章
- C/C++调用Golang 二
C/C++调用Golang 二 <C/C++调用Golang 一>简单介绍了C/C++调用Golang的方法步骤,只涉及一个简单的函数调用.本文总结具体项目中的使用场景,将介绍三种较复杂的 ...
- electron/nodejs实现调用golang函数
https://www.jianshu.com/p/a3be0d206d4c 思路 golang 支持编译成c shared library, 也就是系统中常见的.so(windows下是dll)后缀 ...
- 在golang中使用 cgo,如何让被嵌入的c语言代码调用golang
https://golang.org/misc/cgo/test/callback.go // Copyright 2011 The Go Authors. All rights reserved. ...
- LevelDB性能测试|Golang调用LevelDB
LevelDB性能测试|Golang调用LevelDB 不同方式使用压力测试 用ssdb,TCP连接方式调用,底层存储levelDB 直接调用Cgo的levelDB (必须保证串行) 直接调用Gola ...
- golang和python互相调用
http://blog.yuanzhaoyi.cn/2018/06/27/golang_python.html python3-ctypes: https://docs.python.org/3.5/ ...
- PHP与Golang如何通信?
PHP与Golang如何通信? 最近遇到的一个场景:php项目中需要使用一个第三方的功能(结巴分词),而github上面恰好有一个用Golang写好的类库.那么问题就来了,要如何实现不同语言之间的通信 ...
- calling c++ from golang with swig--windows dll(一)
calling c++ from golang with swig--windows dll 之前项目组开发的项目核心代码全部使用C++语言,新项目可能会引入golang,花了一天多时间研究了wind ...
- Golang丰富的I/O 二----cgo版Hello World
h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...
- GO语言的进阶之路-Golang高级数据结构定义
GO语言的进阶之路-Golang高级数据结构定义 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们之前学习过Golang的基本数据类型,字符串和byte,以及rune也有所了解, ...
随机推荐
- Tomcat 日志分割
一.前言 随着每天业务的增长,Tomcat 的catalina.out日志 变得越来越大,占用磁盘空间不说.要查看某个时候的日志的时候,庞大的日志让你顿时无从下手,所以日志的切割的变得刻不容缓.而且, ...
- 缓存与ABP Redis Cache
缓存与ABP Redis Cache 为什么要用缓存 为什么要用缓存呢,说缓存之前先说使用缓存的优点. 减少寄宿服务器的往返调用(round-trips). 如果缓存在客户端或是代理,将减少对服务器的 ...
- Java设计模式之单例模式详解
在Java开发过程中,很多场景下都会碰到或要用到单例模式,在设计模式里也是经常作为指导学习的热门模式之一,相信每位开发同事都用到过.我们总是沿着前辈的足迹去做设定好的思路,往往没去探究为何这么做,所以 ...
- HttpClient(一)HttpClient抓取网页基本信息
一.HttpClient简介 HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包, 并且它支 ...
- Python 开发与接口测试学习笔记
这是我跟着虫师学习中积累下来的学习笔记,写得比较简单,适合想学习Python开发与接口测试的初学者学习. 一.开发投票系统 1.参考官网文档,创建投票系统. https://docs.djangopr ...
- 基于Jmeter的接口自动化测试实践
在去年实施了一年的三端(PC.无线M站.无线APP[Android.IOS])后,今年7月份开始,我们开始进行接口自动化的实施,目前已完成了整个框架的搭建以及接口的持续测试集成.今天做个简单的分享. ...
- 机房收费系统——转换list泛型时,字段名称不正确应出现故障
因为之前对泛型研究了一番,所以就開始尝试着在机房收费系统重构中增加了泛型的使用. 可是到了做学生查看剩余金额这个功能的时候,还是依照之前的方法做的,可是在载入数据的时候班级这个框就没有显示出来--然后 ...
- JavaScript面向对象编程(9)高速构建继承关系之整合原型链
前面我们铺垫了非常多细节.是为了让大家更加明晰prototype的使用细节: 如今能够将前面的知识整合起来,写一个函数用于高速构建基于原型链的继承关系了: function extend(Child, ...
- RecyclerView高速通用适配Adapter
RecyclerView Adapter 为RecyclerView提供更简单的适配器实现方式,不断更新完好中. Demo视频演示 GitHub地址 博客 使用 BaseViewHolder 的使用 ...
- vue-router实例
最近刚刚用vue写了个公司项目,使用vue-cli构建的,算是中大型项目吧,然后这里想记录并且分享一下其中的知识点,希望对大家有帮助,后期会逐渐分享:话不多说,直接上代码!! main.js // T ...