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
Make string return value from callback available #751
Conversation
7ac0b90
to
6315827
Compare
0e0c05b
to
5da6c7b
Compare
5da6c7b
to
3e0661d
Compare
Thank you for your contribution! I'm not the original author of the related code, but I'm pretty sure there is a reason why That's because the ruby String object that is returned by the block could get GC'ed as soon as the block has ended and so the string data can get invalid at this point in time. In fact the same is true for a JRuby doesn't accept TypeError: invalid callback return type: STRING I think this check should be implemented here in C-FFI as well. I'm not convinced, that adding |
Callbacks returning a :string type were not supported so far. It was possible to define such a callback, but the value returned was NULL in any case. This implementation follows the semantics for passing :string parameters to functions as implemented in Call.c. That means in particular usage of StringValueCStr(), so that no zero bytes are allowed in the string. Special care has to be taken regarding lifetime of the returned text pointer. The C pointer to the string is only valid until the next GC triggering function is called, unless the String object is hold in Ruby outside of the callback block. Even when the object is stored outside of the Ruby block, the text pointer can move when GC.compact is called. So :string returning callbacks can safely be used only, when the referenced text is processed immediately by the calling C function. Resolves ffi#751
Callbacks returning a :string type were not supported so far. It was possible to define such a callback, but the value returned was NULL in any case. This implementation follows the semantics for passing :string parameters to functions as implemented in Call.c. That means in particular usage of StringValueCStr(), so that no zero bytes are allowed in the string. Special care has to be taken regarding lifetime of the returned text pointer. The C pointer to the string is only valid until the next GC triggering function is called, unless the String object is hold in Ruby outside of the callback block. Even when the object is stored outside of the Ruby block, the text pointer can move when GC.compact is called. So :string returning callbacks can safely be used only, when the referenced text is processed immediately by the calling C function. Resolves ffi#751
Callbacks returning a :string type were not supported so far. It was possible to define such a callback, but the value returned was NULL in any case. This implementation rejects :string return type of callbacks. The reason for the reject is the following: In contrast to :string parameters to called functions there is no well defined ownership of the memory of the string returned by callbacks. Instead an explicit FFI::MemoryPointer or similar should be used, which allows to track the validity of underlying memory instead of relying on some Ruby implementation details. Fixes ffi#751
Callbacks returning a :string type were not supported so far and did not work. It was possible to define such a callback, but the value returned was NULL in any case. This implementation rejects :string return type of callbacks at the definition. The reason for the reject is the following: In contrast to :string parameters to called functions there is no well defined ownership of the memory of the string returned by callbacks. Instead an explicit FFI::MemoryPointer or similar should be used, which allows to track the validity of underlying memory instead of relying on some Ruby implementation details. Fixes ffi#751
Background
When a
callback
is defined, the return value isn't made available to the underlying C code if the return value is astring
memory pointer; instead, it would returnnull
to the caller.Disclaimer
Tested with two return values:
FFI::MemoryPointer.from_string()
string
value (does not work yet)Reference
Tested with
Ruby code
C code