C/C++调用Golang 一

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

 

 

 

 

 

 

 

 

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.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++工程中调用godll.dll  

 

创建名为callgovs 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编译时会报符号未定义的错误:

 

posted @ 2017-09-06 20:33  majianguo  阅读(15758)  评论(1编辑  收藏  举报