概述
去年的时候还在发愁如何用 Go 语言编译 DLL 文件, 今年就已经完全实现了,谷歌这样做是非常明智的。
编译过程中需要 gcc 的支持,Windows 环境下的 gcc 系统是 MinGW,去官网下载即可。地址是:
https://sourceforge.net/projects/mingw-w64/
编写 Go 语言程序:exportgo.go
package main
import "C"
import "fmt"
//export PrintBye
func PrintBye() {
fmt.Println("From DLL: Bye!")
}
//export Sum
func Sum(a int, b int) int {
return a + b;
}
func main() {
// Need a main function to make CGO compile package as C shared library
}
注意:
- 注释 //export PrintBye 和 //export Sum 在编译 DLL 的时候是必须的,说明了 DLL 需要输出的函数。注意注释和下面的函数名之间不能有空行。
- 函数 main 也是必不可少的,但是不知道是否能够用它来做 DLL 的初始化,这个以后再仔细研究。
编译生成 DLL 文件
MinGW 安装后有一个叫做 Run terminal 的快捷方式,运行后进入命令行方式,进入 exportgo.go 所在目录,运行如下命令:
go build -buildmode=c-shared -o exportgo.dll exportgo.go
编译生成 exportgo.dll 和 exportgo.h 两个文件。
查看 DLL 的输出函数
有很多工具可以查看 DLL 的输出函数,我下载了 dllexp.exe 查看其内容,发现输出的内容很多,不知道是否有办法屏蔽掉没用的函数。当然,很容易找到我们的输出函数:
查看 exportgo.h 头文件
生成的 exportgo.h 文件也很重要,不仅可以让我们明白如何用 C 语言调用这个 DLL 库,也为用其他语言调用这个库提供了确切的参考指南。其中 Go 语言的内置数据类型在 C 语言中的等价声明,可以仔细看一下,对理解 Go 语言的数据结构很有帮助。
文件 exportgo.h
/* Code generated by cmd/cgo; DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-export-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
#endif
/* 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 GoInt64 GoInt;
typedef GoUint64 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_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
#ifndef GO_CGO_GOSTRING_TYPEDEF
typedef _GoString_ GoString;
#endif
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 void PrintBye();
extern GoInt Sum(GoInt p0, GoInt p1);
#ifdef __cplusplus
}
#endif
用 C# 调用 DLL
using System;
using System.Runtime.InteropServices;
namespace HelloWorld
{
class Hello
{
[DllImport("exportgo.dll", EntryPoint="PrintBye")]
static extern void PrintBye();
[DllImport("exportgo.dll", EntryPoint="Sum")]
static extern int Sum(int a, int b);
static void Main()
{
Console.WriteLine("Hello World!");
PrintBye();
Console.WriteLine(Sum(33, 22));
}
}
}
最后
以上就是忧伤蚂蚁为你收集整理的Golang 编译生成 DLL 文件编写 Go 语言程序:exportgo.go编译生成 DLL 文件查看 DLL 的输出函数查看 exportgo.h 头文件用 C# 调用 DLL的全部内容,希望文章能够帮你解决Golang 编译生成 DLL 文件编写 Go 语言程序:exportgo.go编译生成 DLL 文件查看 DLL 的输出函数查看 exportgo.h 头文件用 C# 调用 DLL所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复