저는 Pony Language의 FFI에서 Window의 CreateProcessA
을 호출하려고했습니다.PonyLang Windows CreateProcess 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에서 완벽하게 작동합니다.
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. 때로는 998을 반환 GetLastError
수익률 123 다른 시간을 반환 는하지만, 내 PonyLang 구현은 0이 아닌 GetLastError
을 반환에 계속? 오류 코드가 다른 경우가 있습니다. 이러한 코드는 모두 파일 액세스에 문제가 있음을 의미합니다.
Calc.exe
은 현재 디렉토리 (예제와 동일한 디렉토리)에 있습니다.
또한 오류 코드가 다르지만 calc.exe는 C 버전에서는 실행되지만 PonyLang 버전에서는 실행되지 않습니다 (정상적으로 실행 됨). 이것은 내 PonyLang ffi 설정으로 뭔가가 떨어져 있다고 믿게합니다.
무엇이 잘못되었을 지 알고 계십니까?
C 코드는 PonyLang 코드와 동일한 버그가 있으며 우연히 만 작동합니다. 오류가 발생했는지 여부를 확인하려면 CreateProcess의 반환 값을 확인해야합니다. * if * 오류가 발생한 경우에만 GetLastError()를 호출하여 오류 코드를 확인하는 것이 좋습니다. 오류가 발생하지 않은 경우 GetLastError()는 아무 것도 반환하지 않을 수도 있지만 0을 반환하지는 않습니다. –
맞지만 C는 calc.exe를 표시하지만 PonyLang은 아무것도 표시하지 않습니다. 팁을 가져 주셔서 감사합니다. 반환 값을 확인하겠습니다. – efel
'BOOL'이 8 비트 타입이라고 가정하고있는 것처럼 보입니다. 실제로 32 비트가되어 문제가 생길 수 있습니다. (또한 CreateProcess에 대한 몇 가지 인수는 포인터 유형이므로 64 비트 응용 프로그램을 빌드하는 경우 32 비트가 아닌 64 비트가 필요합니다. –