-
Notifications
You must be signed in to change notification settings - Fork 68
String parameter support #508
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
Comments
This package could take either of those two options (or have it configurable). Currently it exposes it as
👍 |
We should also add this to the readme's FAQ section(we don't have one currently). |
OK, the following works for me: This page helped me for the conversion: And then IntelliSense (like) feature showed me 'cast<>()'. I am new to Dart but a long time veteran of C, C++, Java (and variants), and Python. Btw, I tried Gluecodium for generating bindings between C++ & Dart, but it tries to also handle Java JNI and Swift and I never got a full build to work although C++ & Dart appeared to complete. Their Hello World is really Hello The Entire World. Aside from strings and forcing myself to use C instead of C++, FFIgen is working well so far (very easy to understand in goes Header and out comes DartBinding). Thanks! |
As an option, add extensions to
import 'dart:ffi';
import 'package:ffi/ffi.dart';
extension StringExtensions on String {
Pointer<Int8> toInt8() {
return Utf8.toUtf8(this).cast<Int8>();
}
}
extension PointerExtensions<T extends NativeType> on Pointer<T> {
String toStr() {
if (T == Int8) {
return Utf8.fromUtf8(cast<Utf8>());
}
throw UnsupportedError('${T} unsupported');
}
}
Utf8.fromUtf8(lib.hello(Utf8.toUtf8('World').cast()).cast()); vs lib.hello('World'.toInt8()).toStr(); @dcharkes @mannprerak2 what do you think? |
The actual API for strings is still up in the air, awaiting dart-lang/sdk#39787. However, it would be fine to add some extension methods in the mean time. extension Utf8PointerString on Pointer<Utf8> { Even better would be to have strings:
- encoding: utf8
functions:
include: sqlite.*
- encoding: ascii
functions:
include: my_function
arguments:
include: my_string This would allocate the right memory, encode/decode the Dart string into that memory, do the ffi call, and free the memory.
@listepo You're leaking the memory backing |
@dcharkes thanks |
extension Utf8PointerString on Pointer<Utf8> {
String toStr() {
final res = Utf8.fromUtf8(this);
free(this);
return res;
}
} @dcharkes did you talk about something like that? |
No. lib.hello('World'.toInt8()).toStr(); Should be: final mallocedString = 'World'.toInt8();
final returnValue = lib.hello(mallocedString).toStr();
free(mallocedString);
return returnValue; |
@dcharkes understood thanks
now it sounds even more important for me :) |
If we were to add string support to ffigen we could generate something like // Input is string instead of pointer
void print(String s) {
_print ??= _dylib.lookupFunction<_c_print, _dart_print>('print');
// convert string to pointer.
final ptr = Utf8.toUtf8(s);
final result = _print(ptr.cast());
// free the pointer.
free(ptr);
return result;
} All conversion logic should still be in We can also do this for the return type of the function (But I am not sure if we can differentiate between I am a little skeptical to add this as converting to and from strings is not always desired (say someone wants to pass string returned by one function to another or say the function modifies the string and returns it, etc) so basically user ends up having And I feel this is something simple enough to be added by the user itself, For |
Maybe it's worth investigating some common patterns, and then decide if they are regular enough to be part of ffigen or not. For SQLite it is always the pattern that the caller keeps ownership of the memory for arguments (so the caller has to free the strings) and that all strings are encoded in utf8. The callee is responsible for the memory backing return values, so you never have to free those.
https://sqlite.org/src/file?name=src/sqlite.h.in&ci=tip This pattern might be different for other libraries. However, if the patterns are very predictable, we could generate something. |
I think this sums up the way
The only benefit I see is that If ffigen converts |
We need an include/exclude structure (in yaml) to make sure that users can include case 1 (for parameters) and 2 (for return values) and users can exclude the last three cases. For case 1 we can automatically allocate the memory and free it after the call. For return values the callee is responsible for memory management (either it's const memory, or there is some other API call for cleaning up resources). |
Another alternative is to provide some kind of API that has a function that is called for each parameter and the return value both before and after the call. That way users could implement this API and use other native calls to do string resource management (for example the way that clang requires you to use api calls to look into and free strings). |
@dcharkes @mannprerak2 is it possible to check that the |
@listepo Not sure if your query is related to this issue, but you can do |
@mannprerak2 thanks |
Now with the Dart SDK 2.12 and its new FFI methods, maybe it makes sense to revisit this issue extension StringUtf8Pointer on String {
Pointer<Utf8> toNativeUtf8({Allocator allocator = malloc})
}
extension Utf8Pointer on Pointer<Utf8> {
String toDartString({int? length})
} |
@vaind can you point us to an API where you'd want to have this? Also, how would like to identify which |
As of
|
This is not working |
@smakarov did you import |
Yes, I don't have any compile errors. Only runtime. |
Could you share the error message? |
It's an internal native library error about wrong file handler. |
@smakarov Okay, since its not related to ffigen, consider asking your question on StackOverflow. |
I don't know where to look in now :( I use the same library with C# wrapper and it works fine. Also it works in Flutter but with local file where I pass String into file parameter, but char *(for playing stream audio file form url) is just not working. |
I've found some strange behavior. |
Bumps [dart-lang/setup-dart](https://github.com/dart-lang/setup-dart) from 1.3 to 1.4. - [Release notes](https://github.com/dart-lang/setup-dart/releases) - [Changelog](https://github.com/dart-lang/setup-dart/blob/main/CHANGELOG.md) - [Commits](dart-lang/setup-dart@6a218f2...a57a6c0) --- updated-dependencies: - dependency-name: dart-lang/setup-dart dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
From what I can gather, strings are not directly supported as parameters. Of course being C and not C++ makes this is a messy topic (char * is not always a string).
Is there anything that can help here? Are there plans for supporting strings?
If strings are somehow supported, then please change the simple example to use them (the other two examples are a bit heavy to teach a conceptually basic type).
The text was updated successfully, but these errors were encountered: