4

I'd like to call this code from my program using LLVM:

#include <string>
#include <iostream>
extern "C" void hello() {
        std::cout << "hello" << std::endl;
}

class Hello {
public:
  Hello() {
    std::cout <<"Hello::Hello()" << std::endl;
  };

  int hello() {
    std::cout<< "Hello::hello()" << std::endl;
    return 99;
  };
};

I compiled this code to llvm byte code using clang++ -emit-llvm -c -o hello.bc hello.cpp and then I want to call it from this program:

#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/IRReader.h>

#include <string>
#include <iostream>
#include <vector>
using namespace std;
using namespace llvm;

void callFunction(string file, string function) {
  InitializeNativeTarget();
  LLVMContext context;
  string error;

  MemoryBuffer* buff = MemoryBuffer::getFile(file);
  assert(buff);
  Module* m = getLazyBitcodeModule(buff, context, &error);
  ExecutionEngine* engine = ExecutionEngine::create(m);    
  Function* func = m->getFunction(function);

  vector<GenericValue> args(0);    
  engine->runFunction(func, args);

  func = m->getFunction("Hello::Hello");
  engine->runFunction(func, args);
}

int main() {
  callFunction("hello.bc", "hello");
}

(compiled using g++ -g main.cpp 'llvm-config --cppflags --ldflags --libs core jit native bitreader')

I can call the hello() function without any problems. My question is: how can I create a new instance of the Hello class using LLVM? I'm getting a segmentation fault when I call Hello::Hello()

Thanks for any hints!!

Manuel

1 Answer 1

3

Running clang++ -emit-llvm on the given source won't emit Hello::Hello, and m->getFunction("Hello::Hello") wouldn't find it even if it were emitted. I would guess it's crashing because func is null.

Trying to directly call functions which aren't extern "C" from the LLVM JIT is generally not recommended... I'd suggest writing a wrapper like the following, and compiling it with clang (or using the clang API, depending on what you're doing):

extern "C" Hello* Hello_construct() {
  return new Hello;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.