英文:
Building a dll with Go 1.7
问题
有没有一种方法可以在Windows下使用Go v1.7构建dll?
我尝试了经典的命令:
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
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只需要一行命令:
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:
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
你好!以下是翻译好的内容:
go build -buildmode=c-archive github.com/user/ExportHello
====> 将会构建 `ExportHello.a` 和 `ExportHello.h`
将在 `ExportHello.a` 中构建的函数重新导出到 `Hello2.c` 中
gcc -shared -pthread -o Hello2.dll Hello2.c ExportHello.a -lWinMM -lntdll -lWS2_32
====> 将会生成 `Hello2.dll`
英文:
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
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文件来导出一个或多个函数。
package main
import "C"
import "fmt"
//export PrintBye
func PrintBye() {
fmt.Println("From DLL: Bye!")
}
func main() {
// 需要一个main函数来将CGO编译包作为C共享库
}
使用以下命令进行编译:
go build -buildmode=c-archive exportgo.go
然后,你需要创建一个C程序(goDLL.c),它将链接上面生成的.h和.a文件。
#include <stdio.h>
#include "exportgo.h"
// 强制gcc链接go运行时(可能有更好的解决方案)
void dummy() {
PrintBye();
}
int main() {
}
使用GCC编译/链接DLL:
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).
package main
import "C"
import "fmt"
//export PrintBye
func PrintBye() {
fmt.Println("From DLL: Bye!")
}
func main() {
// Need a main function to make CGO compile package as C shared library
}
Compile it with:
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
#include <stdio.h>
#include "exportgo.h"
// force gcc to link in go runtime (may be a better solution than this)
void dummy() {
PrintBye();
}
int main() {
}
Compile/link the DLL with GCC:
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上进行了测试,这个方法完美运行:
> go version
go version go1.17.2 windows/amd64
> cat main.go
package main
import (
"C"
)
//export Entry
func Entry(){
main()
}
func main() {
// do something
}
> go build -buildmode=c-shared -o mydll.dll main.go
> dumpbin /EXPORTS mydll.dll
File Type: DLL
..
ordinal hint RVA name
1 0 ... Entry
> rundll32.exe .\mydll.dll,Entry
英文:
Just tested on Windows 10 and this works perfectly:
> go version
go version go1.17.2 windows/amd64
> cat main.go
package main
import (
"C"
)
//export Entry
func Entry(){
main()
}
func main() {
// do something
}
> go build -buildmode=c-shared -o mydll.dll main.go
> dumpbin /EXPORTS mydll.dll
File Type: DLL
..
ordinal hint RVA name
1 0 ... Entry
> rundll32.exe .\mydll.dll,Entry
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论