C/C++調用Golang 一golang
(開發環境:windows
用一個簡單的例子演示如何在C++中調用golang程序。用golang編寫一個簡單的函數,編譯成動態連接庫,而後在C++中調用該go函數。函數
第一階段 將Golang代碼編譯成動態連接庫 (涉及2個文件 main.go和godll.def)ui
Golang : main.go 一個簡單的Add函數spa
package main操作系統
import "C"命令行
//export Add3d
func Add(a, b int32) int32 {blog
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編譯時會報符號未定義的錯誤: