C/C++调用Golang 一

摘要:
用golang编写一个简单的函数,编译成动态链接库,然后在C++中调用该go函数。第一阶段将Golang代码编译成动态链接库Golang:main.go一个简单的Add函数packagemainimport"C"//exportAddfuncAddint32{returna+b}funcmain(){}为动态链接库指定导出符号,创建godll.defEXPORTSAdd将main.go编译成动态链接库,在命令行中执行如下操作:gobuild-buildmode=c-archivegobuild生成了两个文件:godll.agodll.h再执行gcc-m32-shared-ogodll.dllgodll.defgodll.a-static-lwinmm-lWs2_32编译后生成godll.dllgodll.h和godll.dll是C++工程需要的,godll.h的内容如下:/*Createdby"gotoolcgo"-DONOTEDIT.*//*package_/Y_/godll*//*Startofpreamblefromimport"C"comments.*//*Endofpreamblefromimport"C"comments.*//*Startofboilerplatecgoprologue.*/#line1"cgo-gcc-export-header-prolog"#ifndefGO_CGO_PROLOGUE_H#defineGO_CGO_PROLOGUE_HtypedefsignedcharGoInt8;typedefunsignedcharGoUint8;typedefshortGoInt16;typedefunsignedshortGoUint16;typedefintGoInt32;typedefunsignedintGoUint32;typedeflonglongGoInt64;typedefunsignedlonglongGoUint64;typedefGoInt32GoInt;typedefGoUint32GoUint;typedef__SIZE_TYPE__GoUintptr;typedeffloatGoFloat32;typedefdoubleGoFloat64;typedeffloat_ComplexGoComplex64;typedefdouble_ComplexGoComplex128;/*staticassertiontomakesurethefileisbeingusedonarchitectureatleastwithmatchingsizeofGoInt.*/typedefchar_check_for_32_bit_pointer_matching_GoInt[sizeof==32/8?

C/C++调用Golang

(开发环境:

  1. 操作系统: windows 7 32位操作系统
  2. C++visual studio 2010
  3. Golanggo version go1.9 windows/386 TDM-GCC-32

用一个简单的例子演示如何在C++中调用golang程序。用golang编写一个简单的函数,编译成动态链接库,然后在C++中调用该go函数。

第一阶段Golang代码编译成动态链接库 (涉及2个文件 main.gogodll.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

C/C++调用Golang 一第1张

C/C++调用Golang 一第2张

main.go编译成动态链接库,在命令行中执行如下操作:

go build -buildmode=c-archive

C/C++调用Golang 一第3张

go build 生成了两个文件:godll.a godll.h

C/C++调用Golang 一第4张

执行gcc -m32 -shared -o godll.dll godll.def godll.a -static -lwinmm -lWs2_32

C/C++调用Golang 一第5张

(需要安装 TDM-GCC-32)

编译后生成godll.dll

C/C++调用Golang 一第6张

godll.hgodll.dllC++工程需要的,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/C++调用Golang 一第7张

第二阶段C++工程中调用godll.dll

创建名为callgovs 2010工程,将godll.h加入到工程,新建main.cpp的源文件:

#include<Windows.h>

#include<stdio.h>

#include"godll.h"

typedefGoInt32 (*funcPtrAdd)(GoInt32 p0, GoInt32 p1);

intmain(){

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);

return0;

}

godll.h中的三行注释掉

//typedef __SIZE_TYPE__ GoUintptr;

typedeffloatGoFloat32;

typedefdoubleGoFloat64;

//typedef float _Complex GoComplex64;

//typedef double _Complex GoComplex128;

C/C++调用Golang 一第8张

编译运行,结果如下图:

C/C++调用Golang 一第9张

注意事项:

main.goimport "C" 这一行一定要有,否则gcc编译时会报符号未定义的错误:

C/C++调用Golang 一第10张

免责声明:文章转载自《C/C++调用Golang 一》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇amd和cmd区别机器学习速成笔记一下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Golang的time.NewTicker周期性定时器使用案例

 Ticker是一个周期触发定时的计时器,它会按照一个时间间隔往channel发送系统当前时间,而channel的接收者可以以固定的时间间隔从channel中读取事件。 一.通过NewTicker函数定义定时器 package main import ( "fmt" "time" ) func main() { //创建...

C++风格与C风格文件读写效率测试-vs2015,vs2017

1 void test_write() 2 { 3 const int TEST_SIZE = 100000000; 4 const char* c_plus_write_file = "H://c_plus_write_file.txt"; 5 const char* c_write_file = "g://c_writ...

【C++】解决c++中cout输出中文乱码问题

问题:cout输出中文乱码。例如下面的代码输出会乱码。 cout << "成功!" << endl; 输出结果:  解决方案: 控制台还原旧版即可,打开程序->右键->属性->使用旧版控制台->重启程序->解决!...

编程学习必备:C++ 学习的 11 本经典书籍推荐

虽然编程语言很多,但是选择C++绝对不会令人失望! 强大,灵活,复杂,C ++的起源可以追溯到40年前,但它仍然是当今使用最广泛的编程语言之一。 成功的程序员在以往的工作和生活中都曾经历过大大小小的不确定性,承受过永无休止的压力。他们之所以能够成功,是因为拥有一个共同点,都深切关注创建软件所需的各项实践。他们将软件开发视为一种需要精雕细琢加以修炼的技艺,...

(转)VC++的Unicode编程

一、什么是Unicode  先从ASCII说起,ASCII是用来表示英文字符的一种编码规范。每个ASCII字符占用1个字节,因此,ASCII编码可以表示的最大字符数是255(00H—FFH)。其实,英文字符并没有那么多,一般只用前128个(00H—7FH,最高位为0),其中包括了控制字符、数字、大小写字母和其它一些符号。而最高位为1的另128个字符(80H...

VS2010/MFC编程入门之前言

鸡啄米的C++编程入门系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的了解了。但是教程中讲的例子只是一个个简单的例程,并没有可视化窗口。鸡啄米在这套VS2010/MFC编程入门教程中将会给大家讲解怎样使用VS2010进行可视化编程,也就是基于窗口的程序。 C++编程入门系列主要偏重于理论方面的知识,目的是让大家打好底子,...