我一直在嘗試從Pony Language的FFI調用Window的CreateProcessA
。PonyLang Windows創建進程FFI
我創建了一個C和一個PonyLang的例子。 C示例很好:
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
void wmain(void) {
STARTUPINFO info={0};
PROCESS_INFORMATION processInfo={0};
CreateProcessA("calc.exe", 0, 0, 0, 0, 0, 0, 0, &info, &processInfo);
if (status == 0)
printf("%d",GetLastError()); // never hits
}
我把calc.exe
放在當前目錄中。這在Windows上完美無瑕。 然而,我PonyLang實現不斷返回非零GetLastError
:
use "lib:kernel32"
primitive _ProcessAttributes
primitive _ThreadAttributes
primitive _Inherit
primitive _Creation
primitive _Environment
primitive _CurrentDir
primitive _StartupInfo
primitive _ProcessInfo
primitive _HandleIn
primitive _HandleOut
primitive _HandleErr
primitive _Thread
primitive _Process
struct StartupInfo
var cb:I32 = 0
var lpReserved:Pointer[U8] tag= "".cstring()
var lpDesktop:Pointer[U8] tag= "".cstring()
var lpTitle:Pointer[U8] tag= "".cstring()
var dwX:I32 = 0
var dwY:I32 = 0
var dwXSize:I32=0
var dwYSize:I32=0
var dwXCountChars:I32=0
var dwYCountChars:I32=0
var dwFillAttribute:I32=0
var dwFlags:I32=0
var wShowWindow:I16=0
var cbReserved2:I16=0
var lpReserved2:Pointer[U8] tag="".cstring()
var hStdInput:Pointer[_HandleIn] = Pointer[_HandleIn]
var hStdOutput:Pointer[_HandleOut]= Pointer[_HandleOut]
var hStdError:Pointer[_HandleErr]= Pointer[_HandleErr]
struct ProcessInfo
var hProcess:Pointer[_Process] = Pointer[_Process]
var hThread:Pointer[_Thread] = Pointer[_Thread]
var dwProcessId:I32 = 0
var dwThreadId:I32 = 0
//var si:StartupInfo = StartupInfo
actor Main
new create(env: Env) =>
var si: StartupInfo = StartupInfo
var pi: ProcessInfo = ProcessInfo
var inherit:I8 = 0
var creation:I32 = 0
var one:I32 = 0
var two:I32 = 0
var three:I32 = 0
var four:I32 = 0
var z:I32 = 0
var p = @CreateProcessA[I8]("calc.exe",
z,
one,
two,
inherit,
creation,
three,
four,
addressof si,
addressof pi)
if p == 0 then
var err = @GetLastError[I32]() // hits this every time.
env.out.print("Last Error: " + err.string())
end
所以上面的代碼編譯爲PonyLang,但GetLastError
大部分時間返回2.有時GetLastError
回報123將返回998其他時間? 有時候,錯誤代碼有些不同,這似乎很奇怪。這些代碼都意味着文件訪問存在一些問題?
Calc.exe
位於當前目錄(與c示例相同的目錄)。
不僅錯誤代碼不同,而且calc.exe在C版本中執行(運行正常),但不在PonyLang版本中執行。這讓我相信我的PonyLang ffi設置有些問題。
有誰知道什麼可能是錯的?
您的C代碼與您的PonyLang代碼具有相同的錯誤,並且只能巧合使用。您必須檢查CreateProcess的返回值以確定是否發生錯誤。只有*如果發生錯誤,調用GetLastError()來確定錯誤代碼是很有意義的。如果沒有發生錯誤,GetLastError()可能會返回任何內容,但不保證返回零。 –
對,但C顯示calc.exe而PonyLang,什麼也沒有。謝謝你的提示。我會檢查返回值。 – efel
它看起來像你假設'BOOL'是一個8位類型,它實際上是32位,也許這是造成麻煩? (也有一些CreateProcess的參數是指針類型的,所以如果你碰巧正在構建一個64位應用程序,它們將需要64位而不是32位。) –