hi,
i saw the docs that show ways to bind functions from a c library.
can i also bind c++ library?
and how do i compile this binding?
which directory and file name and file extension that i need to put into,
and what command do i need to invoke and require the binding to be able to use the library?
and where should i place the library? will compiled binary works? or i need to get the c library source code to compile for crystal use?
thank you
As far as am I'm aware, C++ symbol mangling is not well specified, so there's no standard we could implement that would work well across libraries compiled with different compilers. For this reason Crystal itself does have a small C wrapper around some of LLVMs C++ only interfaces, providing well defined symbol names: https://github.com/crystal-lang/crystal/blob/master/src/llvm/ext/llvm_ext.cc
The binding is regular Crystal code, you put it into a regular Crystal file and require it, like any other Crystal code. The @[Link]
attribute defines flags that will be included in the final linker invocation, so you should put a shared or static library into your standard linker paths (or extend it by setting LIBRARY_PATH
or specifying the -L
flag either in the @[Link]
attribute or the --link-flags
option to the crystal build
command), which provides the symbol names you specified in the binding.
Crystal does not read the libraries C code in any way currently, nor tries to compile it, it just links against it.
I'm closing this. The explanation @jhass gave is correct: C++ symbol mangling is not well specified.
Since C++ is capable to build libraries, and thus libraries can be interacted with from C++, I guessed it was possible to have some compatibility layer.
I found out, there is a compiler level compatibility, with no exact specifications, but, an incredible peraon, Agner Fog, analyzed and reversed the mangling of a bunch of compilers, and there are 2 major ones: MSVC and GNU 3 (with GNU 4 being a slight evolution). The specs can be found at the following addresses:
So, it may be possible to write a C++ bindings generator. That being said, it may be a crazy, and hard, task.
(that could open up a huge world, though: LLVM, QT, Unity, the Unreal Engine, ...)
Let's make _static_ stubs generated at compile time. It will not let connect methods dynamically, but 95% of code would not need it! If we require that C++ class definition will initially be include into .cr source, we can do it rather simple:
cppClass = CppStub.class({
header_path: "/path/to/headers",
library: "/where/so/or/dll/whatever",
class_name: 'Point', constructors: [ (Int32, Int32) ],
method: (name: "length", args: [], return: Float64), attribute: {name: "x", return: Float64...
})
then the crystal compiler (of compiler plugin if any) extracts it and creates cc bridge code for it (sort of):
#include "cpp2crystal.h"
#include "path_to_lib/include/point.h"
extern "C" bridge_for_Point_contructor1;
CPPRESULT bridge_for_Point_contructor1(int i1,int i2) {
try {
return CPP_OK(new Point(i1, i2));
}
catch(std::exception& e) {
return CPP_ERROR(e.what());
}
catch(...) {
return CPP_ERROR(NULL);
}
}
The same way it creates C-stubs for each method calls and maybe even for property acceess. LLVM could compile it in separate process while main code is being compiled, then we link it together, use existing C bridge code of crystal and get full-sized C++ integration in our executable. Why don't we? as @ysbaddaden said, the huge wold waits. It will really add a great value to crystal lang.
Great! Thank you!
On Wed, Dec 5, 2018 at 11:57 AM Julien Portalier notifications@github.com
wrote:
See https://github.com/Papierkorb/bindgen
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/crystal-lang/crystal/issues/3098#issuecomment-444408497,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AASUIYlqGfRFa6Fls0H7-Kdx0dT_Rf9Yks5u14pmgaJpZM4JdfV2
.
Most helpful comment
(that could open up a huge world, though: LLVM, QT, Unity, the Unreal Engine, ...)