You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在LLVM中实现隐式extern C?调用外部C++函数遇阻求助

Solution for Calling extern "C" C++ Functions from LLVM IR

Let's break down your problem and walk through the solutions step by step—your errors stem from missing library loading steps for both JIT execution and static linking.

1. First: Correctly Build Your extern "C" Function as a Dynamic Library

First, ensure your function is compiled into a shared library that exposes the undecorated printd symbol (thanks to extern "C" preventing C++ name mangling).

Save your function in printd.cpp:

#include <cstdio>

// Platform-specific export annotation (handles Windows/Linux/macOS)
#ifdef _WIN32
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT
#endif

extern "C" DLLEXPORT double printd(double X) {
    fprintf(stderr, "%f\n", X);
    return 0;
}

Compile it into a dynamic library:

Linux/macOS

g++ -shared -fPIC printd.cpp -o libmylib.so

Windows (MSVC)

cl /LD printd.cpp /link /OUT:mylib.dll

Windows (Clang)

clang -shared printd.cpp -o mylib.dll

Verify the symbol is undecorated (Linux/macOS):

nm -D libmylib.so | grep printd

You should see a line like 0000000000001129 T printd (no mangled names like _Z6printdd).

2. Fix clang Linking Errors

When linking your IR with clang, you need to specify the library path and name explicitly:

Linux/macOS

clang out.ll -L. -lmylib -o a.out

Run the executable:

./a.out

You'll see 10.000000 printed to stderr.

Windows

Link against the generated .lib (MSVC) or .dll (Clang):

# MSVC-generated library
clang out.ll mylib.lib -o a.exe

# Clang-generated library
clang out.ll mylib.dll -o a.exe

3. Run with lli (JIT Execution)

lli doesn't load custom libraries by default. Use the --dlopen flag to tell it to load your shared library:

Linux/macOS

lli --dlopen ./libmylib.so out.ll

Windows

lli --dlopen mylib.dll out.ll

This resolves the printd symbol and runs your IR successfully.

4. Implement a Custom JIT (C++ Code)

If you're writing your own LLVM JIT code (instead of using lli), use LLVM's ORC JIT framework (ORCv2 is the current standard) to load your dynamic library. Here's a minimal example:

#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/SourceMgr.h"

using namespace llvm;
using namespace llvm::orc;

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);

  cl::opt<std::string> InputFile(cl::Positional, cl::desc("<input LLVM IR file>"));
  cl::opt<std::string> LibPath("lib", cl::desc("Path to dynamic library"));
  cl::ParseCommandLineOptions(argc, argv, "Custom JIT for external C function\n");

  // Create LLJIT instance
  auto JIT = LLJITBuilder().create();
  if (!JIT) {
    errs() << "Failed to create JIT: " << toString(JIT.takeError()) << "\n";
    return 1;
  }

  // Load the external library into the JIT's symbol search space
  if (!LibPath.empty()) {
    auto Err = JIT->getMainJITDylib().addGenerator(
        ExitOnError()(DynamicLibrarySearchGenerator::Load(LibPath)));
    if (Err) {
      errs() << "Failed to load library: " << toString(std::move(Err)) << "\n";
      return 1;
    }
  }

  // Parse the input LLVM IR file
  SMDiagnostic Err;
  auto M = parseIRFile(InputFile, Err, JIT->getContext());
  if (!M) {
    Err.print(argv[0], errs());
    return 1;
  }

  // Add the IR module to the JIT
  ExitOnError()(JIT->addIRModule(std::move(M)));

  // Look up and execute the main function
  auto MainSym = ExitOnError()(JIT->lookup("main"));
  using MainFn = int (*)();
  auto Main = reinterpret_cast<MainFn>(MainSym.getAddress());
  return Main();
}

Compile this with LLVM libraries (adjust paths if your LLVM is in a non-standard location):

g++ jit_example.cpp `llvm-config --cxxflags --ldflags --system-libs --libs core executionengine orcjit irreader` -o jit_example

Run it with your IR and library:

./jit_example out.ll --lib ./libmylib.so

内容的提问来源于stack exchange,提问作者zoecarver

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:24:26