1. 程式人生 > >C/C++調用Golang 一

C/C++調用Golang 一

style share ace .dll truct 結果 ted lin clu

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.goimport "C" 這一行一定要有,否則gcc編譯時會報符號未定義的錯誤:

技術分享

C/C++調用Golang 一