【问题标题】:How can I call this native function from F#? (LLVMCreateJITCompilerForModule)如何从 F# 调用此本机函数? (LLVMCreateJITCompilerForModule)
【发布时间】:2012-08-25 20:58:34
【问题描述】:

我正在使用llvm-fs 绑定,我想调用的一种方法是createJITCompilerForModule,它是LLVM C api 中本机方法LLVMCreateJITCompilerForModule 的外部。 llvm-fs 的作者表示他无法在 F# 中制作此函数调用的“好”版本:

createJITCompilerForModule in llvm-fs:Generated.fs:

[<DllImport(
    "LLVM-3.1.dll",
    EntryPoint="LLVMCreateJITCompilerForModule",
    CallingConvention=CallingConvention.Cdecl,
    CharSet=CharSet.Ansi)>]
extern bool createJITCompilerForModuleNative(
    void* (* LLVMExecutionEngineRef* *) OutJIT,
    void* (* LLVMModuleRef *) M,
    uint32 OptLevel,
    void* OutError)
// I don't know how to generate an "F# friendly" version of LLVMCreateJITCompilerForModule

你知道我将如何从 F# 调用这个函数,甚至原生函数的作用吗? 看起来它有一个 OutJIT 的“输出参数”(因为原生代码重新分配void* 指向的东西)。这里是原生函数:

LLVMCreateJITCompilerForModule in llvm-c:ExecutionEngineBindings.cpp:

LLVMBool LLVMCreateJITCompilerForModule(LLVMExecutionEngineRef *OutJIT,
                                        LLVMModuleRef M,
                                        unsigned OptLevel,
                                        char **OutError) {
    std::string Error;
    EngineBuilder builder(unwrap(M));
    builder.setEngineKind(EngineKind::JIT)
           .setErrorStr(&Error)
           .setOptLevel((CodeGenOpt::Level)OptLevel);
    if (ExecutionEngine *JIT = builder.create()) {
        *OutJIT = wrap(JIT);
        return 0;
    }
    *OutError = strdup(Error.c_str());
    return 1;
}

【问题讨论】:

  • 您是否尝试过以明显的方式从 F# 调用它(就像普通函数一样)?似乎一切都是正确的
  • 您的问题具体是什么? void* 要传递什么?很可能是nativeint

标签: f# llvm dllimport llvm-c++-api llvm-fs


【解决方案1】:

我想使用的实际功能是一种特殊的手工制作,因为它无法生成。我把它放在这里作为如何调用它的示例:

llvm-fs:ExecutionEngine.fs

let private createEngineForModuleFromNativeFunc
        (nativeFunc : (nativeint * nativeint * nativeint) -> bool)
        (moduleRef : ModuleRef) =

    use outEnginePtr = new NativePtrs([|0n|])
    use outErrPtr = new NativePtrs([|0n|])
    let createFailed =
            nativeFunc (
                outEnginePtr.Ptrs,
                moduleRef.Ptr,
                outErrPtr.Ptrs)
    if createFailed then
        let errStr = Marshal.PtrToStringAuto (Marshal.ReadIntPtr outErrPtr.Ptrs)
        Marshal.FreeHGlobal (Marshal.ReadIntPtr outErrPtr.Ptrs)
        failwith errStr
    else
        ExecutionEngineRef (Marshal.ReadIntPtr outEnginePtr.Ptrs)

let createJITCompilerForModule (modRef : ModuleRef) (optLvl : uint32) =
    let f (engPtr, modPtr, outErrPtr) =
        createJITCompilerForModuleNative (engPtr, modPtr, optLvl, outErrPtr)

    createEngineForModuleFromNativeFunc f modRef

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-06
  • 1970-01-01
相关资源
最近更新 更多