Вызов mono-2.0-sgen.dll с помощью syscall "не является допустимым приложением Win32" - PullRequest
0 голосов
/ 22 марта 2019

Я хочу запустить HelloWorldConsole.exe с поставляемой Mono Framework через Go.

Итак, я хочу назвать функцию mono-2.0-sgen.dll "mono_main" для запуска exe. mono-2.0-sgen.dll - это исполняемый файл PE32 для MS Windows, см. .

Но я получаю сообщение об ошибке "не является допустимым приложением 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()

Имя функции

mono-2.0-sgen.dll

Полная ошибка:

panic: Failed to load C:\Program Files (x86)\Mono\bin\mono-2.0-sgen.dll: %1 is **not a valid Win32 application**.

1 Ответ

0 голосов
/ 24 марта 2019

% 1 не является допустимым приложением Win32

Ошибка %1 is not a valid Win32 application - описание кода ошибки Win32 из самой Windows.

Сам код ошибки Win32 0x000000C1 ERROR_BAD_EXE_FORMAT, см. docs.microsoft.com .

BAD_EXE_FORMAT означает, что вы вызываете dll x86 в процессе x64. Вы должны использовать вариант Go для x86, например, go1.12.1.windows-386.zip из https://golang.org/dl/.

Теперь необходимо изменить GOROOT и PATH на извлеченную папку bin, и тогда вы готовы к работе.

Тип аргументов

Когда вы вызываете mono_main, вам нужно правильно использовать эту функцию. Если вы посмотрите на реализацию , вы увидите, что подпись 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 argummentData [260]byte
    ptr := unsafe.Pointer(&argummentData)

    copy(argummentData[:], dotNetAssembly)

    args := [2]uintptr{0, uintptr(ptr)}

    _, _, _ = lazyProc.Call(2, uintptr(unsafe.Pointer(&args)))
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...