-
-
Notifications
You must be signed in to change notification settings - Fork 48
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
Missing mechanism to pass/receive struct values into/from FFI C functions #183
Comments
Just to link back to the discussion around this that happened in chat, here's the relevant Zulip thread: https://ponylang.zulipchat.com/#narrow/stream/189985-beginner-help/topic/FFI.20receiving.20a.20struct.20(value).20crashes.2E A summary of my main thoughts on this issue, as expressed there:
|
During sync. Another point that was discussed as an option was that we could do code generation of the boilerplate associated with functionality as it stands. |
Note that @Praetonus mentions ponylang/ponyc#2012 (comment) that an interface for clang needed to be exposed and we were doing this because it wasn't exposed. It might be possible that it has since been exposed. The last comment is "I'm going to submit a patch to Clang to expose that interface.". I have no idea what happened with that. |
We would love it if someone would look into interfacing with clang and report back on the feasibility. |
@SeanTAllen: any thoughts coming out of the sync re: the short-term solution proposed by @jemc since that would not require the things to maybe have happened over at Clang? |
I'm personally more in favor of code generation rather than putting something that is broken back in. However, the something that might have happened, if it happened could be the best (and a fairly quick) path forward. More information is needed and whoever undertakes writing an RFC would ideally look into and weigh the pros and cons of each approach and present them in the RFC. |
If anyone is interested in the nuance of the conversation so far that happened at the sync, you can download the recording at https://sync-recordings.ponylang.io/r/2020_09_08.m4a. Getting that nuance would be a good idea for anyone who is interested in writing an RFC for this. |
We discussed this briefly at sync and believe that between last week's recording (for nuance) and what is on this issue should be enough for someone to draft an RFC for this. If you are interested in exploring the issues here in, go for it. |
We discussed this again today at sync and @ergl is looking into this more and will be working on an RFC. |
The commit ponylang/ponyc@221169b removed, on the basis of some C ABI-dependent unexpected behaviors/bugs, the only mechanism to pass value structs into FFI functions or to receive them. In the commit, a proposal was made to use libclang to access the correct call signatures and the removal of tuples for FFI functions was intended to be an interim measure until such a change was made:
"... This change is a temporary measure to avoid spurious FFI bugs until we have the interoperability detailed above. LLVM intrinsics are still allowed to return and be passed tuples since their signatures are defined by LLVM."
A little more than 3 years later no solution is in sight, now somewhat putting into question the decision to entirely remove the ability to wrap C functions that expect or return struct values. This severely limits the ability to wrap large C libraries with fairly simple value structs such as sfVector2f below for which the tuple solution might have worked fine! There are hacks one can use to make this work for this specific struct or structs of good-natured size.
Given the usefulness of a mechanism to pass or receive value structs in FFI scenarios and given the lack of progress that would have justified the removal of the tuple mechanism from the language althogether, I propose to either renable the passing and receiving of tuples (revert the above commit) or to provide a mechanism by which chunks of raw byte data can be generated, cast into Pony primitives, and passed into or received from FFI C functions. Unfortunately, even the hack workarounds shown below only work if by chance the struct size matches the size of a Pony primitive like U32, U64 etc. The struct sfVector3f with three floats cannot be worked around this way since there is no U96 or I96 in Pony.
----------------------------- Detailed example
Take, for example, the following C library wrapped in Pony as "debugstruct.lib"
This currently can't be made to print the sfVector2f struct with Pony code such as:
For this specific 64-bit struct, this can be made work by a hack that involves both, another C function that casts the two float-struct into a unsigned long long in C, and misinforming Pony about the signature of the C function.
This will print
1.000000, 2.000000
. Another way to accomplish this hack would be to something likeThe text was updated successfully, but these errors were encountered: