Как я могу вызвать эту нативную функцию из F#? (LLVMCreateJITCompilerForModule)

Я использую привязки llvm-fs и один метод, который я хотел бы вызвать, это createJITCompilerForModule, который является внешним по отношению к собственному методу LLVMCreateJITCompilerForModule в API LLVM C. Автор 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;
}

person Callum Rogers    schedule 31.08.2012    source источник
comment
Пробовали ли вы вызывать его из F# очевидным образом (как обычную функцию)? Вроде все правильно   -  person John Palmer    schedule 31.08.2012
comment
В чем конкретно ваш вопрос? Что пройти за void*? Скорее всего nativeint.   -  person Daniel    schedule 31.08.2012


Ответы (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
person Callum Rogers    schedule 04.09.2012
comment
Я вижу, ты сам это понял. К вашему сведению, если вы столкнетесь с другими проблемами, у меня больше шансов увидеть это на groups.google.com/forum/?fromgroups#!forum/llvm-fs - person Keith; 18.09.2012