你正在使用哪个版本的Go( go version
)?
go version go1.14.1 windows/amd64
这个问题在最新版本中是否重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
set GO111MODULE=auto
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\anon\AppData\Local\go-build
set GOENV=C:\Users\anon\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\anon\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\anon\AppData\Local\Temp\go-build481521658=/tmp/go-build -gno-record-gcc-switches
你做了什么?
我尝试构建一个c共享库
package main
import "fmt"
import "C"
//export test
func test() {
fmt.Println("Hello World!")
}
func main() {
}
该存档与一个C链接,该C只是调用 test()
,如下所示:
gcc main.c -L<path to dll folder> -l<dll name without extension> -o test.exe
执行 test.exe
不会产生任何输出。
你期望看到什么?
一个有效的dll文件(Windows上的标准动态库格式)
你看到了什么?
调用 go build -buildmode=c-shared
没有产生一个有效的dll(我认为;默认情况下它没有任何扩展名)。它产生了一个没有扩展名的 [folder name]
文件。
我不确定发生了什么,但是如果你尝试将其链接到一个C main
,那么 main
函数不会被执行。链接器不会对文件(将[name]重命名为[name].dll)产生任何警告或错误。
如果你用 go build -buildmode=c-shared -o <name>.dll
生成存档,一切都按预期工作,但 go build -buildmode=c-shared
应该足够了,但它并没有。
7条答案
按热度按时间biswetbf1#
我在Linux上也测试了这个。在Linux上也有相同的行为。该命令生成一个没有扩展名的输出文件。
ut6juiuv2#
@Sebi2020 我认为这正如预期的那样工作。
如果你运行
go build -buildmode=c-shared
命令,它会创建一个没有扩展名的输出文件。
如果你想要特定的文件名,只需使用
-o
参数。例如:go build -buildmode=c-shared -o a.dll
7eumitmz3#
@alexbrainman,这就是bug报告的重点,因为它应该输出一个带有扩展名的文件。对于共享对象或动态链接库来说,没有扩展名的情况并不常见。在Linux上,它们应该以.so结尾,而在Windows上,它们(默认情况下)应该以.dll结尾。
除此之外,如果你没有使用-o标志指定名称,那么在Windows上编译器将不会创建一个有效的.dll文件(后续链接失败)。
628mspwn4#
@Sebi2020 我并不反对你的论点。但我建议你使用 -o 标志来解决你的问题,而不是让 go 命令为你输出文件选择文件名。
我已经很多年没有使用
-buildmode=c-shared
模式了,而且我可能错了。但是,我怀疑你会发现,无论如何都不能重命名输出文件。所以你的论点是没有意义的。Alex
3vpjnl9f5#
@alexbrainman 什么意思是你不能重命名输出文件?我认为这是go工具的简单代码行,必须更改以获取文件扩展名。例如,-o可以默认为[packagename].so而不是[packagename]在linux上和[packagename].dll在windows上。
jtw3ybtb6#
你的意思是你不能重命名输出文件?
运行上一条命令会弹出这个框
Alex
ukqbszuj7#
是的,这种情况确实发生过。因为我了解到,文件名是在dlls中编码的。你需要使用-o选项。但我的意思是,命令应该默认生成一个带有.dll或.so扩展名的文件。