LLVM automatic C++ linking - c++

In some of the LLVM tutorials I'm seen where it's fairly easy to bind C function into a custom language based on LLVM. LLVM hands the programmer a pointer to the function that can be then be mixed in with the code being generated by LLVM.
What's the best method to do this with C++ libraries. Let's say I have a fairly complex library like Qt or Boost that I want to bind to my custom language. Do I need to create a stub library (like Python or Lua require), or does LLVM offer some sort of foreign function interface (FFI)?

In my LLVM code, I create extern "C" wrapper functions for this, and insert LLVM function declarations into the module in order to call them. Then, a good way to make LLVM know about the functions is not to let it use dlopen and search for the function name in the executing binary (this is a pain in the ass, since the function names need to be in the .dynsym section, and it is slow too), but to do the mapping manually, using ExecutionEngine::addGlobalMapping.
Just get the llvm::Function* of that declaration and the address of the function as given in C++ by &functionname converted to void* and pass these two things along to LLVM. The JIT executing your stuff will then know where to find the function.
For example, if you wanted to wrap QString you could create several functions that create, destroy and call functions of such an object
extern "C" void createQString(void *p, char const*v) {
new (p) QString(v); // placement-new
}
extern "C" int32_t countQString(void *p) {
QString *q = static_cast<QString*>(p);
return q->count();
}
extern "C" void destroyQString(void *p) {
QString *q = static_cast<QString*>(p);
q->~QString();
}
And create proper declarations and a mapping. Then you can call these functions, passing along a memory region suitably aligned and sized for QString (possibly alloca'ed) and a i8* pointing to the C string data for initialization.

If you compile some code in C++ and some in another language to LLVM bitcode, it should be perfectly possible to link these together and let one call the other... in theory.
In practice, you will need glue code to convert between the different language's types (e.g. there is no equivalent to a Python string in C++ unless you use CPython, so for void reverse(std::string s) to be callable with a str you need a conversion - worse, the whole object model is very different). And Qt specifically has a lot of magic that may require much more effort to expose after compilations. Also, there may be further potential problems I'm not aware of.
And even if that works, it's potentially very ugly to use. There are still get* and set* functions all over PyQt despite Python's very convenient descriptors - and much effort went into PyQt, they didn't just create some stubs.

Related

How does it work and compile a C++ extension of TCL with a Macro and no main function

I have a working set of TCL script plus C++ extension but I dont know exactly how it works and how was it compiled. I am using gcc and linux Arch.
It works as follows: when we execute the test.tcl script it will pass some values to an object of a class defined into the C++ extension. Using these values the extension using a macro give some result and print some graphics.
In the test.tcl scrip I have:
#!object
use_namespace myClass
proc simulate {} {
uplevel #0 {
set running 1
for {} {$running} { } {
moveBugs
draw .world.canvas
.statusbar configure -text "t:[tstep]"
}
}
}
set toroidal 1
set nx 100
set ny 100
set mv_dist 4
setup $nx $ny $mv_dist $toroidal
addBugs 100
# size of a grid cell in pixels
set scale 5
myClass.scale 5
The object.cc looks like:
#include //some includes here
MyClass myClass;
make_model(myClass); // --> this is a macro!
The Macro "make_model(myClass)" expands as follows:
namespace myClass_ns { DEFINE_MYLIB_LIBRARY; int TCL_obj_myClass
(mylib::TCL_obj_init(myClass),TCL_obj(mylib::null_TCL_obj,
(std::string)"myClass",myClass),1); };
The Class definition is:
class MyClass:
{
public:
int tstep; //timestep - updated each time moveBugs is called
int scale; //no. pixels used to represent bugs
void setup(TCL_args args) {
int nx=args, ny=args, moveDistance=args;
bool toroidal=args;
Space::setup(nx,ny,moveDistance,toroidal);
}
The whole thing creates a cell-grid with some dots (bugs) moving from one cell to another.
My questions are:
How do the class methods and variables get the script values?
How is possible to have c++ code and compile it without a main function?
What is that macro doing there in the extension and how it works??
Thanks
Whenever a command in Tcl is run, it calls a function that implements that command. That function is written in a language like C or C++, and it is passed in the arguments (either as strings or Tcl_Obj* values). A full extension will also include a function to do the library initialisation; the function (which is external, has C linkage, and which has a name like Foo_Init if your library is foo.dll) does basic setting up tasks like registering the implementation functions as commands, and it's explicit because it takes a reference to the interpreter context that is being initialised.
The implementation functions can do pretty much anything they want, but to return a result they use one of the functions Tcl_SetResult, Tcl_SetObjResult, etc. and they have to return an int containing the relevant exception code. The usual useful ones are TCL_OK (for no exception) and TCL_ERROR (for stuff's gone wrong). This is a C API, so C++ exceptions aren't allowed.
It's possible to use C++ instance methods as command implementations, provided there's a binding function in between. In particular, the function has to get the instance pointer by casting a ClientData value (an alias for void* in reality, remember this is mostly a C API) and then invoking the method on that. It's a small amount of code.
Compiling things is just building a DLL that links against the right library (or libraries, as required). While extensions are usually recommended to link against the stub library, it's not necessary when you're just developing and testing on one machine. But if you're linking against the Tcl DLL, you'd better make sure that the code gets loaded into a tclsh that uses that DLL. Stub libraries get rid of that tight binding, providing pretty strong ABI stability, but are little more work to set up; you need to define the right C macro to turn them on and you need to do an extra API call in your initialisation function.
I assume you already know how to compile and link C++ code. I won't tell you how to do it, but there's bound to be other questions here on Stack Overflow if you need assistance.
Using the code? For an extension, it's basically just:
# Dynamically load the DLL and call the init function
load /path/to/your.dll
# Commands are all present, so use them
NewCommand 3
There are some extra steps later on to turn a DLL into a proper Tcl package, abstracting code that uses the DLL away from the fact that it is exactly that DLL and so on, but they're not something to worry about until you've got things working a lot more.

Call a cocoa/obj-c method from a C++ dylib in MAC OS X

Since I am fairly new to Objective-C programming language, I'm facing a huge problem: how can I call a method of my application (made in Objective-C) from my dynamically loaded library (made in C++), by passing it some parameters?
I've been digging the web for a couple of days with no luck. The only thing I found is about IMP, but I'm not sure if that's what I need.
You actually have a plethora of options here.
If the dylib is one of your own, you can compile it as Objective-C++ for Mac OS X and #ifdef the objective-C calls (or not if you are only targeting Mac OS)
Both Obj-C and C++ can make use of C interfaces, so you could write an adapter layer in C (remember Obj-c is a strict superset of C) and expose it for the dylib to call the C functions which then call the Obj-C code.
You can use Blocks, which work in C, C++, and of course Obj-C
you can include the objective-c runtime (see documentation) and muck with that (This is where you would use the *IMP thing you mentioned).
Yet another option might be to use Objective C++ from the Cocoa side to setup C++ objects and expose those to the dylib. How you would go about this really depends on what the library is and how it is used etc; we need to know more about the dylib and how it is being used to elaborate on this.
Since you specifically mention using an IMP lets talk a bit more in depth about that. The declaration is typedef void (*IMP)(id self, SEL _cmd, ...); which you can see takes a pointer to an Obj-C objects, and a SEL (selector), which is just a special C-String representation of the method. You can read more about both SEL and IMP in the documentation.
You can also make use of the runtime's C functions such as objc_msgSend to call a method by passing a pointer to the object and a SEL just like with IMP.
This should be enough information to get you started. Thanks for this question BTW, I never really sat down and thought about all the possible ways to combine C++ with Objective-C before. Odds are I even missed something ;)
You can use objective c runtime
include <objc/runtime.h>
objc_msgSend(id, SEL, arg0, ...)
where
id - is the object where you want to send message
SEL - is struct pointer, describing message you send.
arg0,... are the arguments that you pass to selector.
For more understanding of runtime, see the source code http://www.opensource.apple.com/source/objc4/
Also you can cast IMP address, and call the function.
int(* foo)(id, SEL, arg) = IMP;
foo(someObject, #selector(someMessage), arg);

How to call indirectly a C function

Let's suppose I have the following function:
int func(int a, char* b, float c)
{
return 42;
}
I am curios if there is a possibility to call this function without:
explicitly calling it (func(1, "abc", 2.4))
creating a function pointer to it, and then calling it via the function pointer.
The function is written in C (or C++) and might be located either in a library (DLL on Windows) or somewhere compiled in the current application. For now let's assume there are no name mangling issues.
However, I know the following:
the name of the function.
the number and type of parameters as text based input (such as "int", "char*", "float").
its return type
I'm open to any suggestions, but I'm somewhat afraid of some lower level assembly hacks, since I'd like this to be as portable as possible.
I'd prefer a C solution, and I'd like to avoid boost::bind...
Edit - some clarifications ...
The one "calling" the "function" is a scripting language's compiled library (DLL). It loads the scripting language (source file) which has "bindings" to exteral "functions" (The ones I am trying to call) and when in the scripting language it encounters "call this external function" it tries to call that external function which might be in a DLL ... or the application which actually loaded the scripting language's DLL...
In order to be able to call functions with parameter types that are not clear at compiler time, I fear you won't come around said "lower level assembly hacks".
In cases where portability to architectures other than x86 or AMD64 isn't relevant, take a look at this wonderful library. It allows OS-unspecific ways of generating native bytecode at runtime and should be the easiest way to fulfil your wishes.
It's still beta, however I'm using it for a while now without encountering any problems.

wrap a c++ library in c? (don't "extern c")

is it possible to wrap a c++ library into c?
how could i do this?
are there any existing tools?
(need to get access to a existing c++ library but only with C)
You can write object-oriented code in C, so if it's an object-oriented C++ library, it's possible to wrap it in a C interface. However, doing so can be very tedious, especially if you need to support inheritance, virtual functions and such stuff.
If the C++ library employs Generic Programming (templates), it might get really hairy (you'd need to provide all needed instances of a template) and quickly approaches the point where it's just not worth doing it.
Assuming it's OO, here's a basic sketch of how you can do OO in C:
C++ class:
class cpp {
public:
cpp(int i);
void f();
};
C interface:
#ifdef __cplusplus
extern "C" {
#endif
typedef void* c_handle;
c_handle c_create(int i)
{
return new cpp(i);
}
void c_f(c_handle hdl)
{
static_cast<cpp*>(hdl)->f();
}
void c_destroy(c_handle hdl)
{
delete static_cast<cpp*>(hdl);
}
#ifdef __cplusplus
}
#endif
Depending on your requirements, you could amend that. For example, if this is going to be a public C interface to a private C++ API, handing out real pointers as handles might make it vulnerable. In that case you would hand out handles that are, essentially, integers, store the pointers in a handle-to-pointer map, and replace the cast by a lookup.
Having functions returning strings and other dynamically sized resources can also become quite elaborate. You would need the C caller provide the buffer, but it can't know the size before-hand. Some APIs (like parts of the WIn32 API) then allow the caller to call such a function with a buffer of the length 0, in which case they return the length of the buffer required. Doing so, however, can make calling through the API horribly inefficient. (If you only know the length of the required buffer after the algorithm executed, it needs to be executed twice.)
One thing I've done in the past is to hand out handles (similar to the handle in the above code) to internally stored strings and provide an API to ask for the required buffer size, retrieve the string providing the buffer, and destroy the handle (which deletes the internally stored string).
That's a real PITA to use, but such is C.
Write a c++ wrapper that does an extern c, compile that with c++, and call your wrapper.
(don't “extern c”)
extern C only helps you to have a names in dll like you see them.
You can use
dumpbin /EXPORTS your.dll
to see what happens with names with extern C or without it.
http://msdn.microsoft.com/en-us/library/c1h23y6c(v=vs.71).aspx
To answer your question... It depends... But it is highly unlikely that you can use it without wrappings. If this C++ library uses just a simple functions and types you can just use it. If this C++ library uses a complex classes structure - probably you will be unable to use it from C without wrapping. It is because the internal of classes may be structured one way or another depending on many conditions (using inference with virtual tables or abstracting. Or in example complex C++ library may have its own object creation mechanisms so you HAVE to use it in the way it is designed or you will get unpredictable behavior).
So, I think, you have to prepare yourself for doing dome wrappings.
And here is a good article about wrapping C++ classes. It the article the Author tells about wrapping C++ classes to C# but he uses C at first step.
http://www.codeproject.com/KB/cs/marshalCPPclass.aspx
If the C++ library is written which can be compiled with C compiler with slight editting (such as changing bool to int, false to 0 and true to 1 etc), then that can be done.
But not all C++ code can be wrapped in C. Template is one feature in C++ that cannot be wrapped, or its nearly impossible.
Wrap it in C++ cpp that calls that dll, and "extern C" in that file you made.

How to call a JNI DLL from C++

I have a task to interface with a dll from a third party company using C++.
The dll package comes with:
the dll itself
a sample Java implementation - consists of a java wrapper(library) generated using the SWIG tool and the the java source file
documentation that states all the public datatypes, enumeration and member functions.
My other colleague is using Java(based on the example in package) to interface with the dll while I'm asked to use C++. The Java example looks straight forward... just import the wrapper and instantiate any class described in the docs..
More info on the dll:
From the docs, it says the dll was programmed using C++
From a hexdump, it shows that it was compiled using VC90 (VS C++ 2008 right?) and something from Dinkumware.
From a depends.exe output, the functions seems to be wrapped under JNI. For example: _Java_mas_com_oa_rollings_as_apiJNI_Server_1disconnect#20
My dilemma:
The dll company is not changing anything in the dll and not providing any other info.
How do i use the member functions in the class from the dll?
I did some simple LoadLibrary() and GetProcAddress and manage to get the address of the public member functions.
But i dunno how to use the functions that has the datatype parameters defined in the dll. For example:
From the docs, the member function is defined as:
void Server::connect(const StringArray, const KeyValueMap) throw(std::invalid_argument,std::out_of_range)
typedef std::map Server::KeyValueMap
typedef std::vector Server::StringArray
how do i call that function in C++. The std::map and std::vector in my compiler (VS 2005) has different functions listing that the one in the dll. For example, from the depends.exe output:
std::map // KeyValueMap - del, empty, get, has_1key,set
std::vector // StringArray - add, capacity, clear, get, isEMPTY, reserve, set, size
Any advice/strategy on how i should solve this? Is it possible to simply instantiate the class like the Java example?
If you are trying to use VS 2005 to try and interface with a DLL that is built using VS2008, your attempts will be mostly doomed unless you can use a plain C interface. Given your description, this is not the case; The runtime libraries differ between VS2005 and VS2008 so there is little chance that the object layout has stayed the same between compilers. The 'something from Dinkumware' that you're referring to is most likely the C++ standard library as ISTR that Microsoft uses the Dinkumware one.
With your above example you're also missing several important pieces of information - the types you describe (Server::StringArray and Server::KeyValueMap) are standard library containers. OK fine, but standard library containers of what? These containers are templates and unless you know the exact types these templates have been instantiated with, you're a little stuck.
Is this DLL intended to be called from C++ at all? The fact that it export a JNI interface suggests that it might not be in the first place. Does it export any other public symbols apart from those that are of the format _Java_...?
Of course if there is no other way in and you must use C++ instead of Java, you might want to look into embedding a JVM into your C++ app and use that to call through to the C++ dll. It's not what I'd call an elegant solution but it might well work.
I don't quite understand the use of C++ standard library data types here. How can Java code provide a std::map argument? Are the arguments you pass in always just "opaque" values you would get as output from a previous call to the library? That's the only way you're going to be able to make it work from code under a different runtime.
Anyway...
When you make a JNI module, you run javah.exe and it generates a header file with declarations like:
JNIEXPORT void JNICALL Java_Native_HelloWorld(JNIEnv *, jobject);
Do you have any such header file for the module?
These symbols are exported as extern "C" if I recall correctly, so if you can get the correct signatures, you should have no issues with name mangling or incompatible memory allocators, etc..
The "#20" at the end of the method signature means that the function is declared "stdcall" and that 20 bytes are put on the stack when the function is called. All these methods should start with a JNIEnv* and a jobject, these will total 8 bytes I believe, on a 32-bit environment, so that leaves 12 bytes of parameters you will need to know in order to generate a correct function prototype.
Once you figure out what the parameters are, you can generate something like this:
typedef void (__stdcall *X)(JNIEnv *, jobject, jint i, jboolean b);
Then, you can cast the result of GetProcAddress to an X and call it from your C++ code.
X x = (X)GetProcAddress(module, "name");
if (x) x(params...);
Unfortunately, what you have doesn't quite look like what I have seen in the past. I am used to having to deal with Java data types from C/C++ code, but it looks like this module is dealing with C++ data types in Java code, so I don't know how relevant any of my experience is. Hopefully this is some help, at least.