首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PonyLang Windows CreateProcess FFI

PonyLang Windows CreateProcess FFI
EN

Stack Overflow用户
提问于 2017-02-14 23:39:23
回答 1查看 379关注 0票数 1

我一直试图从Pony的FFI中调用Window的CreateProcessA

我创建了一个C和一个PonyLang示例。C示例工作得很好:

代码语言:javascript
复制
#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

代码语言:javascript
复制
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设置中,有些东西是错的。

有人知道可能出了什么问题吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-17 05:45:22

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

如果您的C函数需要一个指向结构的指针,那么在执行FFI调用时,您可以在不使用addressof的情况下传递Pony对象。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42238248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档