You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update: I still haven't had time to circle back to this, but the fundamental challenge is that I am not sure exactly how to do the ownership of this object type if it is going to be used as a member of an FFI::C::Struct (or FFI::C::Union, which could be quite complicated). The pattern used elsewhere in FFI::C is that if the pointer was allocated in C space it should not be free'd automatically, but it was allocated in Perl space it should be free'd when the object falls out of scope. This is easy to deal with for nested data, but more complicated with pointers. The eventual goal here is to have an FFI::C::String that could be used when defining members of an FFI::C::Struct or FFI::C::Array.
The work around for now is to use an opaque pointer and write a accessor method that converts from/to opaque as appropriate: (caveat example code has not been tested for syntax or anything like that)
packageFoo {
FFI::C->struct([
_string_ptr=>'opaque',
]);
# read-only, for data allocated and free'd in C spacesubstring ($self)
{
$ffi->cast('opaque', 'string', $self->_string_ptr);
}
}
packageFoo {
use FFI::Platypus::Memory qw( free strdup );
FFI::C->struct([
_string_ptr=>'opaque',
]);
# read-write, for data allocated and free'd in Perl spacesubstring ($self, $new_value=undef)
{
if(defined$new_value) {
if(defined$self->_string_ptr) {
free $self->_string_ptr;
}
$self->_string_ptr(strdup $new_value);
}
$ffi->cast('opaque', 'string', $self->_string_ptr);
}
substring_free ($self)
{
if(defined$self->_string_ptr) {
free $self->_string_ptr;
$self->_string_ptr(undef);
}
}
}
Another option is to use FFI::Platypus::Record, which has both string_ro and string_rw types, where the assumption is that for string_ro C owns the data and is therefore read-only and not free'd by Perl, and that for string_rw Perl owns the data and is therefore read-write and IS free'd by Perl when the record falls out of scope. We could in theory do something similar for FFI::C but that doesn't seem like the right approach for FFI::C
Whatever approach we eventually decide on, we have to consider how to handle pointers to strings in Unions. I don't think there is an obvious automatic way to do it, and we might just have to disallow string pointers inside of a union. If you need that capability you can still define an opaque pointer member and manage the reads by casting and allocation manually.
None of this applies to a fixed length string, which is nested inside of a struct, this sort of data structure is basically the same as a fixed array of char.
This would wrap around a pointer to a null terminated C style string. Some integration with opaque member on a struct/union would be helpful.
The text was updated successfully, but these errors were encountered: