Skip to content
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

Add support for Struct passed or returned by value? #262

Open
basshelal opened this issue Aug 17, 2021 · 2 comments
Open

Add support for Struct passed or returned by value? #262

basshelal opened this issue Aug 17, 2021 · 2 comments

Comments

@basshelal
Copy link
Contributor

We do not support Structs passed by value as parameters or as return types, any mapping using a Struct is automatically assumed to be a Struct Pointer in C and thus causes strange cryptic errors at load time.

typedef struct MyStruct {
    int a;
    int b;
} MyStruct;

// supported
MyStruct *struct_by_pointer_function(MyStruct *s);
void struct_by_pointer_function_param(MyStruct *s);
MyStruct *struct_by_pointer_function_return(void);

// unsupported
MyStruct struct_by_value_function(MyStruct s);
void struct_by_value_function_param(MyStruct s);
MyStruct struct_by_value_function_return(void);

A possible API could be something like this:

public interface MyLib {
    @Struct.ByValue MyStruct struct_by_value_function(@Struct.ByValue MyStruct struct);
    
    @Struct.ByPointer MyStruct struct_by_pointer_function(@Struct.ByPointer MyStruct struct);

    // same as above, Struct.ByPointer is the default
    MyStruct struct_by_pointer_function(MyStruct struct);
}

I toyed around with this a little but didn't know where exactly go, the code is quite convoluted. I know that Arrays by value do work and that JFFI has support for structs as returns and using the heap parameter buffer we can make structs as parameters work too. The issue is the memory copy that has to be done both ways as the memory is not heap based and direct like most Pointers we use, but rather probably transient memory so it needs to be copied both ways. I could be wrong on this though I didn't have much time (or enthusiasm) to pursue it much further.

This is a lot more complicated than I am probably willing to dedicate time and effort to at least for now, especially since this is mostly a non-issue since very few C libraries will use struct by value because of the performance implications it causes. So this isn't very high priority, I'm just logging this here for reference in case someone wants to comment on this or fix it later.

@headius
Copy link
Member

headius commented Aug 18, 2021

This is indeed a good idea and I agree with your assessment that it would need to be copied at every call. The simplest option would probably be to have such structs never maintain a native pointer and immediately copy the entire contents into the new Java struct object, later copying those contents back out to a native on-stack struct. I also agree that the code is convoluted. We may need to take a few steps back first and try to clean up and document more code in jffi and jnr-ffi just so we can get a handle on how all the pieces fit together; since wmeissner left the project, we have struggled with this.

@basshelal
Copy link
Contributor Author

I wholeheartedly agree with you on this! We need to raise the level of quality and grasp on the entire codebase by better documentation and more/better tests. The code is extremely elegant and efficient but it's lacking in the clarity factor which would help maintainability and rate of improvements.
I will do everything I can regarding this, splitting into small PRs for easy merge and quicker changes, but I've been busy with annoying real life stuff so it could be a little slow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants