如何使用 llvm api for c++ 访问函数中的指针

问题描述 投票:0回答:0

出于某种目的,我想使用一种专用语言。基本上它将是一堆我将从 C 代码调用的函数。我需要将这些函数指针传递给某个结构。我不想通过实验来检查我是否知道如何获得该函数,我编写了一个小程序,该程序应该采用结构的整数并将其加 2。当我试图获取指向结构元素的指针时出现错误。 注意:我完成了万花筒教程,所以我从那里获取了一些对象。 代码: // 结构定义:

struct test_struct {
    char *b;
    int *c_dummy;
    int c;
    double f ;
};
struct test_struct tt{0,0,1,0};

// 初始化。

InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
TheJIT = ExitOnErr(KaleidoscopeJIT::Create());
TheContext = std::make_unique<LLVMContext>();
TheModule = std::make_unique<Module>("my cool jit", *TheContext);
TheModule->setDataLayout(TheJIT->getDataLayout());
Builder = std::make_unique<IRBuilder<>>(*TheContext);
TheFPM = std::make_unique<legacy::FunctionPassManager>(TheModule.get());
TheFPM->add(createCFGSimplificationPass());
TheFPM->doInitialization();

// 创建值 2 稍后添加。

Value *v_const = ConstantInt::get(*TheContext,APInt(32,2,true));
// 函数的返回类型:
Type *r_type = Type::getVoidTy(*TheContext);
// 在 llvm

中定义结构参数
   ArrayRef<Type *> params = {Type::getInt8PtrTy(*TheContext),Type::getInt32PtrTy(*TheContext),
    Type::getInt32Ty(*TheContext),Type::getDoubleTy(*TheContext)};
    StructType *st = StructType::create(*TheContext,"s");
    st->setBody(params);

// 获取函数并注册到模块。获取条目 BB 并进行加法。

    Value *c;
    BasicBlock *bb = BasicBlock::Create(*TheContext,"entry",F);
    Builder->SetInsertPoint(bb);
    Value *mem= Builder->CreateAlloca(st,nullptr); // This should allocate the param to stack.
    // create a stac allocation for st.
    for (auto &arg : F->args())
    {
        // bring st from the argument.
        auto &tmp_ar = arg;
        c = Builder->CreateStructGEP(st,&arg,2);
    }
    /* Store the argument in the stack*/
    Builder->CreateLoad(c,mem);  
    // perform add
    Builder->CreateAdd(mem,v_const,"add tmp");
    // close of.
    Builder->CreateStore(mem,c);
    Builder->CreateRetVoid();

现在我用这个函数测试它:


void do_test()
{
    auto fsym = ExitOnErr(TheJIT->lookup("test"));
    void (*add_func)(struct test_struct *) = (void (*)(struct test_struct *))(intptr_t)fsym.getAddress();
    printf("Before func: %d\n", tt.c);
    add_func(&tt); // this should change t.c
    printf("After func: %d\n", tt.c);

}

我得到了我不明白的错误: test_ptr: /usr/lib/llvm-14/include/llvm/Support/Casting.h:269: typename llvm::cast_retty::ret_type llvm::cast(Y*) [with X = llvm::PointerType; Y = llvm::类型; typename llvm::cast_retty::ret_type = llvm::PointerType*]:断言 `isa(Val) && “cast() 参数不兼容类型!”失败。 中止

因为这条线而发生:

   c = Builder->CreateStructGEP(st,&arg,2); 

我期待它运行并打印正确的值。我编译了:g++ -g test_ptr.cpp

llvm-config --cxxflags --ldflags --system-libs --libs core orcjit native
-O0 -o test_ptr

c++ compiler-construction llvm clang++
© www.soinside.com 2019 - 2024. All rights reserved.