-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ffi: comparison with Calypso, feature set, limitations? #1
Comments
Hi! We also used libclang quite a bit to generate wrappers before. For simple C APIs that's fine. The major downside is that each codebase needs some tweaking and dealing with #if/def is sometimes just not possible.
Code is only emitted, not parsed, so it's mostly a matter of coming up with a Nim-syntax. A downside is the lack of linting/auto completion in Nim. For diagnostics we have to rely on the C++ compiler.
In general the stdlib will work fine. Templates are still a bit cumbersome and instantiations have to be declared manually. I'd love to end up with something like
We were working with a few big code bases, including LLVM, but there is still a lot manual work involved. The main obstacle would be templates and inheriting from C++ types right now. We would like to get to a point where namespaces, types, enum-members, etc. can all be accessed through a syntax like
There is no overhead. All calls directly emit C++ code using
Templates are not yet supported. For our use cases we imported template classes/functions manually so far. This is very possible though and mostly about coming up with a nice syntax that looks like Nim generics.
When using
We would love to turn the things in this repo into standalone/stdlib modules once they are more mature!
We had some issues with
This will stay necessary for now. All "dynamic" method calls return a Nim type that doesn't correspond to a C++ type. The compiler would emit a local variable with that "fake" type without
I remember issues with generic converters... |
thanks for all the answers!
Here's how Calypso handles mapping C++ templates to D templates (example, for std::vector): https://github.com/Syniurge/Calypso/blob/master/tests/calypso/libstdc%2B%2B/vector.d, eg:
# in module opencv.nim
let val = My::Sub::Namespace::MyEnum.SomeValue
type MyEnumAlias = My::Sub::Namespace::MyEnum
assert MyEnumAlias.SomeValue == val
# in module use_opencv.nim, ie user code
from opencv import nil
let val = opencv.My::Sub::Namespace::MyEnum.SomeValue
|
Some template magic in the emitted C++ should be able to take care of distinguishing between fields, types, etc. Generics and subtypes don't look too hard. I didn't have a good idea for namespaces yet though. When using a single operator for both, distinguishing on the C++ side is tricky though. While it's probably possible to template the emitted code depending on whether the right side is a type, instance/static field, etc., I didn't come up with a way to "overload" the emitted code for namespaces yet... |
First of all thank you for this motivating discussion. The drive of this cpp ffi since the beginning was always productivity, paying the price of precision and correctness leading to sub optimal linting (jsffi has the same issue), the need to specify the proper nim types and in the case of templates to qualify them as a real type. Like @jwollen said we experimented with libclang a lot, results were not optimal, c++ is very hard and some complex libraries like for example LLVM itself use templates in every possible way, properly supporting everything needs too much maintenance cost. In the future I see us trying to add more compile time magic, specially never forgetting that c++ has compile time magic as well and combining smartly nim and c++ meta-programming might reach the best results with a minimal time investment compared to maintaining a full LLVM compiler pass. template usage example
basically we qualify them into a concrete nim type, ideally using nim templates would be nice but for now this works nicely.
As soon as we implement a |
just heard of fragments through https://t.me/nim_lang ; I'm curious to what extent it fullfills what I was looking for in nim-lang/Nim#8327?
std::vector<T>
(note: should provide a view over data, not a mere copy)?design discussions
scratch below here
template cppnewref*(myRef: ref CppObject, arg0: typed, arg1: typed): untyped =
.to(void)
=> ugly but could be necessary due to a bug in Nim ; forgot what that bug wasconverter toShort*(co: CppProxy): int16 {.used, importcpp:"(#)".}
+ friends =>convertTo(int16)
(ie make these generic usingtypedesc
)minor
let win_incl = ($lib).replace("/", "\\").quoteShell
blocksecho $global.globalNumber.to(cint)
=>$
superfluous (+ all such cases)The text was updated successfully, but these errors were encountered: