这里有一个奇怪的 - 通过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中没有看到任何问题)。
有什么想法吗?
jeck猫
相关分类