windows - PonyLang Windows CreateProcess FFI

标签 windows ffi pony ponylang

我一直在尝试从 Pony Language 的 FFI 调用 Window 的 CreateProcessA

我创建了一个 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 设置出了问题。

有谁知道哪里出了问题?

最佳答案

问题出在您对 addressof 的使用上。当您创建一个 struct 对象时,例如对于 var si = StartupInfo,底层类型是指向结构的指针(即 Pony 中的 struct 没有值语义)。然后,当您使用 addressof 调用 CreateProcessA 时,您实际上传递了一个指向该函数的指针。

如果您的 C 函数需要一个指向结构的指针,您可以在执行 FFI 调用时简单地传递没有 addressof 的 Pony 对象。

关于windows - PonyLang Windows CreateProcess FFI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42238248/

相关文章:

ruby-on-rails - 主机名与服务器证书不匹配-无法发送电子邮件

ruby - 小马和续集的协会有冲突吗?

ruby-on-rails - Rails 邮件程序 Ubuntu

Haskell:如何获取#define-d 常量的值?

windows - Powershell脚本适用于服务器,但不适用于cloudformation cfn-init函数

c - 在 Windows shell 命令中嵌入 Python 代码

java - 是否需要 Java 才能运行某些基于 .NET 的程序?

c - 如何使用 FFI 从 C 调用 Rust 结构的方法?

haskell - 如何从外部代码确定数据的构造函数?

C# SSL 流 - 系统重启后证书错误