if i have written a library in C++, and have bindings for C, Ada, Fortran, D & other compiled languages.
could all these bindings be in the same binary with the C++ compiled code even if they use the same function names?
and could you use the bindings like this?
Depending how you create your bindings a library may not be even necessary:
Bindings written some interpreter specific APIs:
For example, ruby extensions written using the MRI API, are basically a shared library providing a:
void init_Modulename()
This function then uses the MRI api like rb_define_module, rb_define_class, rb_define_method, etc to wrap the C/C++ APIs. Make sure this function is surrounded by extern "C" so it's name does not get mangled in the C++ way.
Normally this shared library goes linked against the library you are binding, but nothing prevents that they are the same shared library.
Bindings done at runtime
For example bindings using FFI on Ruby and other interpreters. The bindings get defined in the same language and it is the FFI library that knows how to call the methods in the target library at runtime. Therefore in this case the bindings themselves have no "library".
Bindings done with generators
If you use a generator, like SWIG, it will scan the library headers and generate the bindings for various languages. Depending on how those targets are implemented by the SWIG generator (for example, for Ruby uses the MRI API described above) then SWIG will create code you can compile into its own library, but as long as you don't have symbol conflicts, you could as well compile this together with your library.
When I mean symbol conflicts, I don't mean the API itself, but the binding helpers, like init_Modulename().
You can link C++ with C, provided you are only calling C style functions (outside of objects) and have turned name mangling off in the header via "extern C". Especially if you are using the same compiler. Different compilers will cause problems if they use different obj formats. I don't know about ADA/Fortran/D, but I suspect the answer will be no, at least directly via .LIB or .OBJ files. On windows, you can try via DLL's if ADA/FORTRAN/D supports dynamic linking (or you can call the windows api LoadLibrary).
This is not an easy thing to do and I glossed over the details. If you are really going to try, then you'll need to be specific about which platforms and compilers you are using and I'll try to be more specific.
Yes. An example (slightly reversed) is PlPlot; it's written in C and has bindings to Ada, C++, D, Fortran77, Fortran95, Java, Lua, OCaml, Python, ...
Related
I am wondering what is the best/most common way to create a C++ library that I could create a wrapper for in another language.For example I if I create a library in C++ I'd like to create a wrapper for it in C# and then later on create a wrapper for the C++ library in Python.
I also want to be able to give the library to another person easily almost like a one file thing if that is possible? Also should I use a Dynamic Link Library or a Static Link Library? Extremely new to this sort of thing thanks.
A very common way that people simplify linking C or C++ code to other languages is through the Simplified Wrapper and Interface Generator. For the language runtimes it supports, it's a much easier to understand interface than integrating closely with each different language you wish to ship your library for.
In general, this will mean creating a dynamic library. Loading a dynamic library is a simple task for any runtime, but loading a static module would require modifying the language runtime. For that reason, it simply doesn't make sense to build a static module for either of your cited use cases.
For Python, with your build properly configured, you can ship your library module as a single dynamic library (barring licensing problems with libraries you link to). However, users will typically expect your module to be packaged using the standard Python setup-tools, as a .egg file.
You should be prepared to learn how each respective language community expects third-party packages to be packaged, to make the introduction of your library to them as easy as possible. Conforming to their expectations makes your library appear more professional, better designed, and easier to consider for their projects.
I would recommend, however, spending some time learning more about the Foreign Function Interface of a few different languages, to familiarize yourself with some of the peculiarities that SWIG sometimes can't hide perfectly. For example, passing a value to the other language requires "boxing" the C++ value into a value type, and then incrementing its reference count. SWIG does this for you, but it's sometimes the case where you have no choice but to write or debug some of that code yourself. Being unfamiliar with how those FFI interfaces work will hinder you substantially.
Suppose I have two projects that I would like to link together:
A C++ library compiled with Visual C++ to a DLL file.
A C++ executable compiled with C++ Builder that uses the classes in the library.
I realize that there is no standard C++ ABI and that any attempts to directly link these two C++ projects together will fail. What is a good, automated way of creating a compatibility layer that allows me to accomplish this?
For example, conceivably the C++ library could expose itself via a C interface. Then the executable would have some C++ classes that wrap the C interface exposed by the C++ library. Since there is a standard ABI for C, it would work.
The only question is how to automatically create the C interface and C++ wrapper classes - manually maintaining this would not be an option. The SWIG project looks promising, but unfortunately, C++ is not one of the exits of SWIG listed on their web site. Is there a way to do what I want with SWIG? Or is there another project other than SWIG that would help me with this task?
Or am I going about this the wrong way?
Edit: The core C++ library is intended to be cross-platform. The executable, obviously, is Windows-specific. I don't want to pollute the core library to the extent that it becomes impossible to compile it on other platforms.
If it only has to run on Windows, I would expose the classes as COM objects. They'll still be in a DLL and they can be used by any language which understands COM.
The "standard" way of doing this, in Windows, is to use COM objects. So, that is certainly a good option to look at. In Linux systems, the module interaction model (e.g., executable-DLL interaction) is very different, and ABIs exist for C++.
If you would want to do this manually (create your own COM-like library), it can be a lot of work with many little tricky issues to take seriously. You'll need a cross-module RTTI system, you'll need an interface query/definition protocol, some mechanism to manage memory across modules, etc. Beyond that, to "automate" it, you will probably need a combination of MACROs and template meta-functions.
One cross-platform option that I would highly recommend that you consider or at least look at is using Boost.Python and the Python language as the "glue" between your modules. The Boost.Python library basically does the whole "automated exporting / importing of classes", but it exports your C++ classes and functions as Python classes and functions. And, it is completely non-intrusive and cross-platform, so this is really an ideal example of automated exporting. So, you might consider using Python to write your high-level glue-code, or using Python as an intermediate between the C++ modules, or even reworking the Boost.Python library to use only the "automated exporting" mechanisms to export to whatever interface system you design or use.
I'm sure there a plenty other similar libraries out there. But the number one question is, of course, do you really need this? You might be using a bazooka to kill a fly.
Why not just compile the library with C++ builder as well?
Looking around at swig (I knew swig should be able to wrap C++ in C):
SWIG and C++
If core library is cross-platform why not also write the UI as a cross-platform Qt application and build everything in Visual C++ on Windows.
By Plugin.
We mean a library that is loaded vi dlopen() and its symbols resolved via dlsym() (not a standard shard library that is dynamically loaded by the runtime system).
Referring to http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/. The document was last updated in 2006. It recommends the use of extern "C" to prevent mangling of function names, so that dlsym can find its functions with relative ease.
Is this still relevant for dynamic libraries? In my particular case, I am trying to create a dynamic library on OSX using libtool. Perhaps using __attribute__ ((constructor)) is more hip and modern, I have had little success discovering the recommended practice.
I'm pretty sure extern "C" is still the best way to export unmangled functions from C++ code. Using it across several platforms without issues.
A runtime plugin
If you plan to load a library manually dlopen() and use dlsym() to retrieve and resolve functions/objects then using a extern "C" name becomes much easier. It is a pain for mangled names.
Thus if you want easier portability/usabilty then use an C (extern "C") interface.
But you should consider the cons to exposing a C (extern "C") interface.
This means you can not expose any of your C++ objects directly via the interface. Thus you are loosing a lot of functionality like RAII initially. You should compensate for this by writing extra wrapper calls to wrap the calls to your C interface
Normal shared libraries
Edit: Original answer:
The original question was about shared libraries (only via comments did we find it was about plugin shared libraries).
So the names are unmanageable.
This is not a problem if the compiler/runtime are resolving the symbols.
Do you plan on using multiple compilers? as this is the only reason I can see for exporting a C interface (as different C++ compiler often use different ABI).
If you are using the same compiler then why not use the C++ interface.
Personally on any given platform I only use one compiler and I only use the shared objects on that platform. If the compiler is upgraded something bigger has happened I am re-build all my libraries anyway.
I've got a lot of c++ code which contains a lot of functions and classes in namespaces (boost, for example).
Now I'm trying to embed LuaJiT2 as script engine, but I cannot find anything about calling functions and using other stuff from namespaces.
So, Is it possible to pass the functions from c++ namespaces to LuaJIT with the FFI?
You may use the standard Lua API to expose namespace-scope functions, as well as class static functions, to Lua. This is done exactly as you would with the regular Lua interpreter, since LuaJIT is drop-in compatible with it.
But you can't use FFI, because FFI is based on a C-based parsing of the header files. And you're using C++ syntax. FFI is not the only way to use LuaJIT; it's just one that is based on C.
Any of the C++-specific binding APIs that use Lua (Luabind, SWIG, etc) should work just fine with LuaJIT as well.
It is possible to use different name mangling other than C. The reason why its not "common" is because the C++ name mangling is very compiler/platform specific:
http://lua-users.org/lists/lua-l/2011-07/msg00502.html
So this sort of declaration is valid:
ffi.cdef[[
void Test1_Method1(void) asm("_ZN5Test17Method1Ev");
]]
And you can then call Test1_Method1.
Mike Pall has done an amazing job with luajit. So many great features.
Are there any high level language that don't support using C++ libraries?
Using C++ libraries from other high-level languages has a couple of major obstacles:
if the library is OO, you need to be able to create a C++ object in the calling language - this is not easy.
C++ implementations use a technique known as "name-mangling" to ensure type-safe linkage. Unfortunately, there is no standard for name mangling, so C++ code cannot even easily be called between different C++ implementations.
So the answer to your question is that most HLLs will have problems calling C++ code. They may also have problems calling any other language of course - there are actually no standardised binary interfaces between languages, except ad hoc, platform-specifc ones.
I can't think of any language that is able to use C++ libraries directly. Even getting C++ to do it can be tricky (if the library was compiled with a different compiler than you're using)
Of course, if you write a wrapper of some kind (either a wrapper for the specific library, or some kind of bindings library that lets you expose specific types), then any language can use C++ libraries. But directly, as-is, with no extra work? I don't think any language other than C++ can do it.
This is a bit of an anti-answer, but many popular high-level languages can have bindings to C++ library code created for them via swig (http://swig.org/).