2012-08-31 27 views
1

我正在使用llvm-fs綁定,我想調用的一種方法是createJITCompilerForModule,它是LLVM C api中本地方法LLVMCreateJITCompilerForModule的外部。 LLVM-FS的作者已表示,他不能在F#一個「好」這個函數調用的版本:如何從F#調用此本機函數? (LLVMCreateJITCompilerForModule)

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; 
} 
+0

你試過從F#調用它的明顯的方式(只是作爲一個正常的功能)?這似乎是一切正確 –

+0

你的問題具體是什麼?什麼傳遞'void *'?最有可能的是'nativeint'。 – Daniel

回答

3

我想用是一個特殊的手的實際功能做一個,因爲它可能不會發生。我已經把它這裏的如何調用它的例子:

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 
+1

我知道你已經明白了你自己。僅供參考如果您碰到其他顛簸,我可以通過https://groups.google.com/forum/?fromgroups#!forum/llvm-fs看到更好的機會 – Keith