Calling Extern Function

Im using example code from interpreter example. Im trying to call an
extern fuction from JIT code, but I can't get it to work.
Ive looked at examples on the net, but some are old and there all different.

How do I register an extern function?

heres some code im using at the moment.
Any help would be great!

// function I want to call
int yipee(int val)
{
  fprintf(stderr, "yipee!");

  return 1;
}

int Execute(llvm::Module *Mod, char * const *envp)
{
...
  llvm::Function *F =
cast<llvm::Function>(Mod->getOrInsertFunction("yipee",
  llvm::Type::getInt32Ty(llvm::getGlobalContext()),
llvm::Type::getInt32Ty (llvm::getGlobalContext()), NULL));
  EE->addGlobalMapping(F, yipee);
  llvm::Function *YipeeFn = Mod->getFunction("yipee");
  if (!YipeeFn) {
    llvm::errs() << "'yipee' function not found in module.\n";
    return 255;
  }
...
}

Can someone please tell me what I am doing wrong?

Im trying to register an external function with the JIT, so can call
functions in my music application(heres an image :
http://img534.imageshack.us/img534/3995/87647073.jpg).

Here my functions

int yipee(int aVar)
{
    return 5;
}

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  // code I have added

I assume you are compiling your program as c++. In this case your problem is that "yipee" will have been name mangled by the c++ compiler.

Yes, it is c++;
ave also tried it with

extern "C"
int yipee(int aVar)
{
    return 5;
}

but still no luck.

heres my full listing, im stuck.

// Whistle.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Support/TypeBuilder.h"
#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Config/config.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
#include "llvm/Target/TargetSelect.h"
using namespace clang;
using namespace clang::driver;

extern "C"
int yipee(int val)
{
  fprintf(stderr, "yipee!");

  return 1;
}

llvm::sys::Path GetExecutablePath(const char *Argv0) {
  // This just needs to be some symbol in the binary; C++ doesn't
  // allow taking the address of ::main however.
  void *MainAddr = (void*) (intptr_t) GetExecutablePath;
  return llvm::sys::Path::GetMainExecutable(Argv0, MainAddr);
}

int Execute(llvm::Module *Mod, char * const *envp) {
  llvm::InitializeNativeTarget();

  std::string Error;
  llvm::OwningPtr<llvm::ExecutionEngine> EE(
    llvm::ExecutionEngine::createJIT(Mod, &Error));
  if (!EE) {
    llvm::errs() << "unable to make execution engine: " << Error << "\n";
    return 255;
  }

  // code I have added

What does nm on your application binary give in terms of the name yipee?
You are not by any chance stripping symbols from your binary?

Possibly you need the equivalent of gcc's -rdynamic flag for your compiler.

I don't know what nm means.

By nm I mean the GNU tool nm which lists the symbols in object files. Are you on a platform that has nm or are you on windows, osx, or something else?

Im not stripping anything.

Good so the symbols should be in the executable.

Honistly, I would of thought an example of this would be provided, it
must be used often.

The example you have should work, the code seems fine. The extern C should overcome any name mangling, which is why I was asking you to check what you get from listing the symbols, asking that you hadn't stripped symbols, and suggesting that if at that stage everything looks good then the only issue could be that dlopen can't see the symbols, which is why I suggested that you may been the equivalent of gcc's -rdynamic flag for your compiler.

He showed up in IRC today and we discovered that he was adding the function twice to the module. I'm not sure what was happening, but that was the side-effect. So he was trying to call yippe1 or something.

Paul: Did you get things working?

-eric

Honistly, I would of thought an example of this would be provided, it
must be used often.

The example you have should work, the code seems fine. The extern C should overcome any name mangling, which is why I was asking you to check what you get from listing the symbols, asking that you hadn't stripped symbols, and suggesting that if at that stage everything looks good then the only issue could be that dlopen can't see the symbols, which is why I suggested that you may been the equivalent of gcc's -rdynamic flag for your compiler.

He showed up in IRC today and we discovered that he was adding the function twice to the module. I'm not sure what was happening, but that was the side-effect. So he was trying to call yippe1 or something.

Right. Yes. I missed this line:

llvm::Function* F = llvm::Function::Create(ft, llvm::Function::ExternalLinkage, "yipee", Mod);

The attempt to lookup yipee was probably finding this symbol which is probably the same as / similar too a failed lookup.