Skip to content

Instantly share code, notes, and snippets.

@sjindel-google
Last active May 19, 2023 04:46
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sjindel-google/b88c964eb260e09280e588c41c6af3e5 to your computer and use it in GitHub Desktop.
Save sjindel-google/b88c964eb260e09280e588c41c6af3e5 to your computer and use it in GitHub Desktop.
Passing strings between Go and Dart (via FFI)
go build -o godart.so -buildmode=c-shared
dart godart.dart
import "dart:ffi";
import "dart:convert";
import 'package:ffi/ffi.dart';
class GoString extends Struct {
Pointer<Uint8> string;
@IntPtr()
int length;
String toString() {
List<int> units = [];
for (int i = 0; i < length; ++i) {
units.add(string.elementAt(i).value);
}
return Utf8Decoder().convert(units);
}
static Pointer<GoString> fromString(String string) {
List<int> units = Utf8Encoder().convert(string);
final ptr = allocate<Uint8>(count: units.length);
for (int i = 0; i < units.length; ++i) {
ptr.elementAt(i).value = units[i];
}
final GoString str = allocate<GoString>().ref;
str.length = units.length;
str.string = ptr;
return str.addressOf;
}
}
typedef logType = Void Function(Pointer<GoString>);
typedef GoLog = void Function(Pointer<GoString>);
main() {
final lib = DynamicLibrary.open("./godart.so");
final GoLog goLog = lib.lookup<NativeFunction<logType>>("Go_Log").asFunction();
final Pointer<GoString> message = GoString.fromString("Hello, Go!");
goLog(message);
free(message);
}
import "dart:ffi";
import "dart:convert";
import 'package:ffi/ffi.dart';
class GoString extends Struct {
Pointer<Uint8> string;
@IntPtr()
int length;
String toString() {
List<int> units = [];
for (int i = 0; i < length; ++i) {
units.add(string.elementAt(i).value);
}
return Utf8Decoder().convert(units);
}
static Pointer<GoString> fromString(String string) {
List<int> units = Utf8Encoder().convert(string);
final ptr = allocate<Uint8>(count: units.length);
for (int i = 0; i < units.length; ++i) {
ptr.elementAt(i).value = units[i];
}
final GoString str = allocate<GoString>().ref;
str.length = units.length;
str.string = ptr;
return str.addressOf;
}
}
typedef logType = Void Function(Pointer<GoString>);
typedef GoLog = void Function(Pointer<GoString>);
main() {
final lib = DynamicLibrary.open("./godart.so");
final GoLog goLog = lib.lookup<NativeFunction<logType>>("Go_Log").asFunction();
final Pointer<GoString> message = GoString.fromString("Hello, Go!");
goLog(message);
free(message);
}
@user1121114685
Copy link

dart:ffi api upgraded, the code works like follow:

class GoString extends Struct {
Pointer p;

@ffi.Int64()
int n;

String toString() {
List units = [];
for (int i = 0; i < n; ++i) {
units.add(p.elementAt(i).value);
}
return Utf8Decoder().convert(units);
}

static GoString fromString(String string) {
List units = Utf8Encoder().convert(string);
var ptr = calloc(units.length);
for (int i = 0; i < units.length; ++i) {
ptr.elementAt(i).value = units[i];
}
GoString str = calloc().ref;
str.n = units.length;
str.p = ptr;
return str;
}
}

typedef _c_Command = GoString Function(GoString data);
typedef _dart_Command = GoString Function(GoString data);

typedef _c_Command2 = GoString Function();
typedef _dart_Command2 = GoString Function();

thank you for the information about the go/dart!

The same does not work in the new version of ffi?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment