How to pass empty pointers?

105 views
Skip to first unread message

rashedmyt

unread,
Aug 16, 2020, 3:47:47 PM8/16/20
to Dart FFI
The use case here is that I want to send a Pointer object as a function argument. The allocation of memory and value takes place on C side. Then I would like to read the value from the pointer on the dart side and free the memory allocated by C. A simple example is given below

void hello(char *text)
{
    std::string hello_world = "hello world";
    text = strdup(hello_world.c_str()); // dynamically allocate and copy value
}

Vyacheslav Egorov

unread,
Aug 19, 2020, 9:27:46 AM8/19/20
to rashedmyt, Dart FFI
The concept you are looking for is pointer to a pointer. 

void hello(char** text) {
  ...
  *text = strdup(hello_world.c_str());
}

To create this on the Dart side you need Pointer<Pointer<Int8>> and then you need to allocate a memory backing it (e.g. using allocate<Pointer<Pointer<Int8>>()), so that C side could store into it. 



--
You received this message because you are subscribed to the Google Groups "Dart FFI" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dart-ffi+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dart-ffi/4d1a86fd-822b-4b29-9bcb-e80ebb6108a4n%40googlegroups.com.

rashedmyt

unread,
Aug 19, 2020, 10:48:39 AM8/19/20
to Dart FFI
I've found another way without having to change the C API.

Pointer<Int64> address = allocate<Pointer<Int64>>();
hello(address.cast());
String value = Utf8.fromUtf8(Pointer.fromAddress(address.value));

The above code works for my case without the need to change the C API. But I'm concerned whether this approach will have any hidden issues which could result in either crash or memory leakage.

Vyacheslav Egorov

unread,
Aug 20, 2020, 3:22:28 AM8/20/20
to rashedmyt, Dart FFI
> The above code works for my case without the need to change the C API. But I'm concerned whether this approach will have any hidden issues which could result in either crash or memory leakage.

I'd expect you had to change C implementation though right? (e.g. did something like *((char**)text) = ...). It's unclear why you would not then just change API to have proper types on the incoming parameters. 

Other then that it's exactly the same thing that I suggested. 

One thing to keep in mind (I forgot to mention it) is that you of course should free what you have allocated, so you need to do free(address) after you no longer need it.

// If you get an email from me outside of the 9-5 it is not because I'm always
// on or expect an immediate response from you; it is because of work flexibility.
// Evening and weekend emails are a sign I allocated some regular working hours
// for other things (such as family, gym, friends,...).  And I encourage you to
// feel free to do the same.



rashedmyt

unread,
Aug 20, 2020, 3:54:54 AM8/20/20
to Dart FFI
I did not change the C implementation even slightly. It's exactly the same as I posted in the first post. I'm assuming it is working because C pointers are integers which store the memory address to read from and I've allocated enough memory to store the integer address.

The other thing regarding memory is that will free(Pointer.fromAddress(address.value)) work since the memory is dynamically allocated on C side and dart doesn't know how much is allocated and should be freed when free is called.

Vyacheslav Egorov

unread,
Aug 20, 2020, 4:12:12 AM8/20/20
to rashedmyt, Dart FFI
> I did not change the C implementation even slightly. 

Then it should not work. The implementation that you have sent before was this one:

void hello(char *text)
{
    std::string hello_world = "hello world";
    text = strdup(hello_world.c_str()); // dynamically allocate and copy value
}

What this does is update variable text to point to a copy of your string. So this should not be visible on the Dart side (e.g. if you pass a pointer to a pointer to this function the memory which is being pointed by text should not be affected). 

> The other thing regarding memory is that will free(Pointer.fromAddress(address.value)) 

That would work as long as you are calling strdup on the C side (which will use malloc), free from Dart side would just call C free which knows how much memory was allocated. (malloc/free implementation takes care of that). 

Note that you need to free both memory pointed by address and memory pointed by a pointer stored at address, in other words you need:

free(Pointer.fromAddress(address.value));
free(address);

// If you get an email from me outside of the 9-5 it is not because I'm always
// on or expect an immediate response from you; it is because of work flexibility.
// Evening and weekend emails are a sign I allocated some regular working hours
// for other things (such as family, gym, friends,...).  And I encourage you to
// feel free to do the same.


rashedmyt

unread,
Aug 20, 2020, 4:19:23 AM8/20/20
to Dart FFI
>  Then it should not work. 
But it is working... I took this https://github.com/dart-lang/sdk/issues/43005 as reference and it worked
Reply all
Reply to author
Forward
0 new messages