下面由golang教程栏目给大家介绍golang 编译成 dll 文件 的方法,希望对需要的朋友有所帮助!
golang 编译 dll 过程中需要用到 gcc,所以先安装 mingw。
windows 64 位系统应下载 mingw 的 64 位版本: https://sourceforge.net/projects/mingw-w64/
下载后运行 mingw-w64-install.exe,完成 minggw 的安装。
首先撰写 golang 程序 exportgo.go:
package mainimport "c"import "fmt"//export printbyefunc printbye() { fmt.println("from dll: bye!")}//export sumfunc sum(a int, b int) int { return a + b;}func main() { // need a main function to make cgo compile package as c shared library}
编译成 dll 文件:
go build -buildmode=c-shared -o exportgo.dll exportgo.go
编译后得到 exportgo.dll 和 exportgo.h 两个文件。
参考 exportgo.h 文件中的函数定义,撰写 c# 文件 importgo.cs:
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)); }
编译 cs 文件得到 exe
csc importgo.cs
将 exe 和 dll 放在同一目录下,运行。
>importgo.exehello world!from dll: bye!55
golang 中的 string 参数在 c# 中可以如下引用:
public struct gostring { public string value { get; set; } public int length { get; set; } public static implicit operator gostring(string s) { return new gostring() { value = s, length = s.length }; } public static implicit operator string(gostring s) => s.value; }
// func.gopackage mainimport "c"import "fmt"//export addfunc add(a c.int, b c.int) c.int { return a + b}//export printfunc print(s *c.char) { /* 函数参数可以用 string, 但是用*c.char更通用一些。由于string的数据结构,是可以被其它go程序调用的,但其它语言(如 python)就不行了*/ print("hello ", c.gostring(s)) //这里不能用fmt包,会报错,调了很久...}func main() { }
编译
go build -ldflags "-s -w" -buildmode=c-shared -o func.dll func.go
还是有点大的,880kb,纯c 编译的只有48kb,应该是没有包含全部的依赖吧,go是全包进来了
go 调用package mainimport ( "fmt" "syscall")func main() { dll := syscall.newlazydll("func.dll") add := dll.newproc("add") prt := dll.newproc("print") r, err, msg := add.call(32, 44) fmt.println(r) fmt.println(err) fmt.println(msg) name := c.cstring("andy") prt.call(uintptr(unsafe.pointer(name)))}
out:760the operation completed successfully.hello andy
python 调用from ctypes import cdll, c_char_pdll = cdll("func.dll")dll.add(32, 33)dll.print(c_char_p(bytes("andy", "utf8")))
c++调用#include <iostream>#include <windows.h>using namespace std;typedef int(*padd)(int a, int b);typedef void(*pprt)(char* s);int main(int argc, char *argv[]){ hmodule dll= loadlibrarya("func.dll"); padd add = (padd)getprocaddress(dll, "add"); pprt prt = (pprt)getprocaddress(dll, "print"); cout << add(321, 33) << endl; prt("andy"); freelibrary(dll); return 0;}
更多相关技术文章,请访问go语言教程栏目!
以上就是详解golang编译成dll文件的详细内容。