go - 使用系统调用调用 mono-2.0-sgen.dll 得到“不是有效的 Win32 应用程序”
问题描述
我想通过 Go 使用随附的 Mono 框架执行 HelloWorldConsole.exe。
所以我想调用mono-2.0-sgen.dll 函数“mono_main”来执行exe。mono-2.0-sgen.dll 是用于 MS Windows 的 PE32 可执行文件,请参阅.
但我收到错误“不是有效的 Win32 应用程序”
_ = os.Setenv("MONO_PATH", `\mono\lib\mono\4.5;C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\Debug`)
_ = os.Setenv("MONO_CFG_DIR", `"C:\Program Files (x86)\Mono\etc"`)
_ = os.Setenv("MONO_CONFIG", `"C:\Program Files (x86)\Mono\etc\mono\config"`)
mono := `C:\Program Files (x86)\Mono\bin\mono-2.0-sgen.dll`
app := `C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\Debug\HelloWorldConsole.exe`
fmt.Println("Execute")
var mod = syscall.NewLazyDLL(mono)
var proc = mod.NewProc("mono_main")
ret, _, _ := proc.Call(0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("mono.exe"))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(app))) )
相同的行为windows.NewLazySystemDLL
dll := windows.NewLazySystemDLL(mono)
lazyProc := dll.NewProc("mono_main")
lazyProc.Call()
函数名称
完全错误:
panic: Failed to load C:\Program Files (x86)\Mono\bin\mono-2.0-sgen.dll: %1 is **not a valid Win32 application**.
解决方案
%1 不是有效的 Win32 应用程序
该错误%1 is not a valid Win32 application
是 Windows 本身对 Win32 错误代码的描述。
Win32 错误代码本身是0x000000C1 ERROR_BAD_EXE_FORMAT
,请参阅docs.microsoft.com。
BAD_EXE_FORMAT
意味着您在 x64 进程中调用 x86 dll。您必须使用 Go 的 x86 变体,例如https://golang.org/dl/中的 go1.12.1.windows-386.zip 。
现在必须将 GOROOT 和 PATH 更改为提取的 bin 文件夹,然后您就可以开始了。
参数类型
当您调用时,mono_main
您需要以正确的方式使用 this 函数。如果您查看实现,您会看到签名是int mono_main (int argc, char* argv[]);
. argc 和 argv 是一种广泛使用的模式,请参见此处。
工作样本
func main() {
_ = os.Setenv("MONO_PATH", `C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\x86\Debug\mono\lib\mono\4.5;C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\x86\Debug\`)
_ = os.Setenv("MONO_CFG_DIR", `C:\DEV\HelloWorhpm.goldConsole\HelloWorldConsole\bin\x86\Debug\mono\etc`)
_ = os.Setenv("MONO_CONFIG", `C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\x86\Debug\mono\etc\mono\config`)
_ = os.Chdir(`C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\x86\Debug\`)
mono := `C:\DEV\HelloWorldConsole\HelloWorldConsole\bin\x86\Debug\mono\bin\mono-2.0-sgen.dll`
// https://github.com/mono/mono/blob/c5b88ec4f323f2bdb7c7d0a595ece28dae66579c/mcs/tools/mkbundle/template_main.c#L1
dll := windows.NewLazySystemDLL(mono)
lazyProc := dll.NewProc("mono_main")
dotNetAssembly := []byte(`HelloWorldConsole.exe`)
var argumentData [260]byte
ptr := unsafe.Pointer(&argumentData)
copy(argumentData[:], dotNetAssembly)
args := [2]uintptr{0, uintptr(ptr)}
_, _, _ = lazyProc.Call(2, uintptr(unsafe.Pointer(&args)))
}
推荐阅读
- php - 如何使用 DB Facades 访问数据库?
- matlab - 在已排序文件的文件夹中查找特定文件
- ruby-on-rails - 在日历中垂直返回同一工作日 - Ruby on Rails
- r - 在 R 中编写函数时,我应该何时使用自己的错误消息?
- javascript - 在 ngFor 中隐藏/显示单个或特定按钮
- python - 如何通过使用 bash 脚本传递参数来运行 python 文件?
- java - JxBrowser 更新浏览器
- javascript - Javascript 表单的意外行为
- java - 如何使用java将对象相互链接
- react-native - 找不到 mapboxgl 的解密文件