使用Go 1.7构建一个dll文件。

huangapple go评论121阅读模式
英文:

Building a dll with Go 1.7

问题

有没有一种方法可以在Windows下使用Go v1.7构建dll?

我尝试了经典的命令:

  1. go build -buildmode=shared main.go

但是得到了以下错误信息:
> -buildmode=shared 在 windows/amd64 上不受支持

更新
好的,我已经找到了答案。对于那些感兴趣的人:
https://groups.google.com/forum/#!topic/golang-dev/ckFZAZbnjzU

英文:

Is there a way to build a dll against Go v1.7 under Windows ?

I tried a classic

  1. go build -buildmode=shared main.go

but get
> -buildmode=shared not supported on windows/amd64

update
Ok, I've got my answer. For those who are interested :
https://groups.google.com/forum/#!topic/golang-dev/ckFZAZbnjzU

答案1

得分: 26

从Go 1.10版本开始,Windows系统现在支持-buildmode=c-shared。

发布说明:
https://golang.org/doc/go1.10#compiler

所以现在编译成DLL只需要一行命令:

  1. go build -o helloworld.dll -buildmode=c-shared

我相信这些头文件只与GCC兼容。如果你只暴露C类型,这应该不是一个大问题。我能够在Visual Studio中使用LoadLibrary而不需要头文件。

英文:

As of Go 1.10, -buildmode=c-shared is now supported on Windows.

Release notes:
https://golang.org/doc/go1.10#compiler

So now compiling to DLL is a one-liner:

  1. go build -o helloworld.dll -buildmode=c-shared

I believe the headers are only compatible with GCC. If you're only exposing C-types, this should not be a big issue. I was able to get LoadLibrary to work in Visual Studio without the header.

答案2

得分: 22

你好!以下是翻译好的内容:

  1. go build -buildmode=c-archive github.com/user/ExportHello
  2. ====> 将会构建 `ExportHello.a` `ExportHello.h`
  3. 将在 `ExportHello.a` 中构建的函数重新导出到 `Hello2.c`
  4. gcc -shared -pthread -o Hello2.dll Hello2.c ExportHello.a -lWinMM -lntdll -lWS2_32
  5. ====> 将会生成 `Hello2.dll`
英文:
  1. go build -buildmode=c-archive github.com/user/ExportHello

====> will build ExportHello.a, ExportHello.h

Take the functions built in ExportHello.a and re-export in Hello2.c

  1. gcc -shared -pthread -o Hello2.dll Hello2.c ExportHello.a -lWinMM -lntdll -lWS2_32

====> will generate Hello2.dll

答案3

得分: 13

在GitHub上有一个项目展示了如何创建一个基于user7155193的答案的DLL。

基本上,你可以使用GCC从生成的Golang的.a和.h文件构建DLL。

首先,你需要创建一个简单的Go文件来导出一个或多个函数。

  1. package main
  2. import "C"
  3. import "fmt"
  4. //export PrintBye
  5. func PrintBye() {
  6. fmt.Println("From DLL: Bye!")
  7. }
  8. func main() {
  9. // 需要一个main函数来将CGO编译包作为C共享库
  10. }

使用以下命令进行编译:

  1. go build -buildmode=c-archive exportgo.go

然后,你需要创建一个C程序(goDLL.c),它将链接上面生成的.h和.a文件。

  1. #include <stdio.h>
  2. #include "exportgo.h"
  3. // 强制gcc链接go运行时(可能有更好的解决方案)
  4. void dummy() {
  5. PrintBye();
  6. }
  7. int main() {
  8. }

使用GCC编译/链接DLL:

  1. gcc -shared -pthread -o goDLL.dll goDLL.c exportgo.a -lWinMM -lntdll -lWS2_32

然后,goDLL.dll可以被加载到另一个C程序、FreePascal/Lazarus程序或你选择的程序中。

完整的代码和一个加载DLL的Lazarus/FPC项目在这里:
https://github.com/z505/goDLL

英文:

There is a project on github which shows how to create a DLL, based on, and thanks to user7155193's answer.

Basically you use GCC to build the DLL from golang generated .a and .h files.

First you make a simple Go file that exports a function (or more).

  1. package main
  2. import &quot;C&quot;
  3. import &quot;fmt&quot;
  4. //export PrintBye
  5. func PrintBye() {
  6. fmt.Println(&quot;From DLL: Bye!&quot;)
  7. }
  8. func main() {
  9. // Need a main function to make CGO compile package as C shared library
  10. }

Compile it with:

  1. go build -buildmode=c-archive exportgo.go

Then you make a C program (goDLL.c) which will link in the .h and .a files generated above

  1. #include &lt;stdio.h&gt;
  2. #include &quot;exportgo.h&quot;
  3. // force gcc to link in go runtime (may be a better solution than this)
  4. void dummy() {
  5. PrintBye();
  6. }
  7. int main() {
  8. }

Compile/link the DLL with GCC:

  1. gcc -shared -pthread -o goDLL.dll goDLL.c exportgo.a -lWinMM -lntdll -lWS2_32

The goDLL.dll then can be loaded into another C program, a freepascal/lazarus program, or your program of choice.

The complete code with a lazarus/fpc project that loads the DLL is here:
https://github.com/z505/goDLL

答案4

得分: 0

只在Windows 10上进行了测试,这个方法完美运行:

  1. > go version
  2. go version go1.17.2 windows/amd64
  3. > cat main.go
  4. package main
  5. import (
  6. "C"
  7. )
  8. //export Entry
  9. func Entry(){
  10. main()
  11. }
  12. func main() {
  13. // do something
  14. }
  15. > go build -buildmode=c-shared -o mydll.dll main.go
  16. > dumpbin /EXPORTS mydll.dll
  17. File Type: DLL
  18. ..
  19. ordinal hint RVA name
  20. 1 0 ... Entry
  21. > rundll32.exe .\mydll.dll,Entry
英文:

Just tested on Windows 10 and this works perfectly:

  1. &gt; go version
  2. go version go1.17.2 windows/amd64
  3. &gt; cat main.go
  4. package main
  5. import (
  6. &quot;C&quot;
  7. )
  8. //export Entry
  9. func Entry(){
  10. main()
  11. }
  12. func main() {
  13. // do something
  14. }
  15. &gt; go build -buildmode=c-shared -o mydll.dll main.go
  16. &gt; dumpbin /EXPORTS mydll.dll
  17. File Type: DLL
  18. ..
  19. ordinal hint RVA name
  20. 1 0 ... Entry
  21. &gt; rundll32.exe .\mydll.dll,Entry

huangapple
  • 本文由 发表于 2016年11月13日 19:41:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/40573401.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定