没有从可执行文件通过Windows Powershell pinvoke go c-shared

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


我做了什么?


我用一个导出的函数(HelloWorld)交叉编译了最简单的c共享dll,我可以为Windows编译。然后,我从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提示符来执行进一步的控制台命令,如“主机名”或“ipconfig”等。


我看到了什么?


这真的很奇怪。HelloWorld()函数确实已成功执行,我在控制台上看到文本“Hello World”。但是,在调用该函数后,我不再能够在 powershell 窗口中看到来自 cmd.exe 命令的任何控制台输出。例如,调用“hostname”只是返回没有输出,“ipconfig”也是如此。


例如,最初主机名.exe工作并提供输出,但在执行cshared dll后,我无法看到主机名的任何进一步输出。控制台上的 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 的输出传递到一个文件(例如,“hostname > out.txt”),那么我可以确认输出是否存在并且命令是否成功(如果您将可执行命令通过管道传输到“Out-Host”cmdlet,也会发生同样的情况)。所以似乎执行c共享的dll以某种方式导致stdout被重定向或无法正确显示?或者关于PS会话的编码要中断的东西?


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


有什么想法吗?


噜噜哒
浏览 104回答 1
1回答

jeck猫

这已被Windows的控制台所有者识别为golang本身中的错误。go问题线程在这里:https://github.com/golang/go/issues/44876
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go