通过 Windows Powershell 调用 go c-shared dll 后,可执行文件没有标准输出

No stdout from executables after pinvoke of go c-shared dll via Windows Powershell

这是一个奇怪的问题 - 在通过 Powershell 从 golang c 共享 dll 中调用一个函数后,可执行文件的后续执行(例如 hostname.exe、ipconfig 等)显示没有输出到标准输出。只有当 powershell 调用 dll 函数时才会发生这种情况(Windows 上的 python 不会重现此问题)。

我做了什么?

我用一个导出函数 (HelloWorld) 为 Windows 交叉编译了最简单的 c 共享 dll。然后我从 Powershell.

调用了 dll

go 代码是:

package main

import "C"
import (
        "fmt"
)

//export HelloWorld
func HelloWorld() {
        fmt.Println("Hello World")
}

func main() {}

使用的构建命令(来自 linux)是:

GOARCH=amd64 GOOS=windows CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc go build -v -buildmode=c-shared -o helloworld.dll .

然后我将生成的 .dll 复制到 Windows 并使用以下 Powershell 脚本调用 HelloWorld() 函数:

$signature = @"
[DllImport("c:\cshared\helloworld.dll")]
public static extern void HelloWorld();
"@

Add-Type -MemberDefinition $signature -Name World -Namespace Hello

[Hello.World]::HelloWorld()

我期待看到什么?

我希望 dll 的 HelloWorld() 函数被成功调用(导致文本“Hello World”被写入控制台)然后我希望能够使用我的 powershell 提示符来执行进一步的控制台命令,例如“hostname”或“ipconfig”等

我看到了什么?

这真的很奇怪。 HelloWorld() 函数确实执行成功,我在控制台上看到文本“Hello World”。但是,调用该函数后,我无法再在我的 powershell window 中看到 cmd.exe 命令的任何控制台输出。例如,仅调用“主机名” returns 而没有输出,“ipconfig”也是如此。

例如最初 hostname.exe 工作并提供输出,但在执行 cshared dll 之后,我无法在控制台上看到 hostname..exe 的任何进一步输出:

PS C:\cshared> hostname
nick-host
PS C:\cshared> hostname
nick-host
PS C:\cshared> .\helloworld.ps1
Hello World
PS C:\cshared> hostname
PS C:\cshared> ipconfig
PS C:\cshared> hostname

如果我将 hostname.exe 的输出通过管道传输到一个文件(例如“主机名 > out.txt”),那么我可以确认输出存在并且命令成功(如果你将可执行命令通过管道传输到“Out-Host”cmdlet)...所以执行 c-shared dll 似乎会导致 stdout 被重定向或无法正确显示?或者关于要中断的 PS 会话的编码?

我尝试从 go 代码中删除 fmt.Println 以查看是否有帮助,但问题仍然相同。我也只在 Powershell 上看到了这一点(如果我做完全相同的实验,但在 Windows 上从 python 调用 helloworld.dll,我看不到任何问题shell 之后)。

有什么想法吗?

Windows 的控制台所有者已将此识别为 golang 本身的错误。 go 问题线程在这里:https://github.com/golang/go/issues/44876