Skip to content

Commit

Permalink
Updated example with strings and simple struct
Browse files Browse the repository at this point in the history
  • Loading branch information
mjohnsullivan committed Aug 2, 2019
1 parent 3315d40 commit 7cdbdd5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
*.dylib
a.out
.vscode/
.packages
sdk-version
*snapshot*
pubspec.lock
25 changes: 17 additions & 8 deletions structs/c/structs.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,30 @@

int main()
{
struct Place place;
place = create_place("My Home", 1.0, 2.0);
printf("The name of my place is %s\n", place.name);
struct Coordinate *coord = create_coordinate(3.5, 4.5);
printf("Coordinate is lat %.2f, long %.2f\n", coord->latitude, coord->longitude);

struct Place *place = create_place("My Home", 1.0, 2.0);
printf("The name of my place is %s at %.2f, %.2f\n", place->name, place->coordinate->latitude, place->coordinate->longitude);

printf("%s\n", hello_world());
printf("%s\n", reverse("backwards", 9));
return 0;
}

struct Place create_place(char *name, double latitude, double longitude)
struct Coordinate *create_coordinate(double latitude, double longitude)
{
struct Coordinate *coordinate = (struct Coordinate *)malloc(sizeof(struct Coordinate));
coordinate->latitude = latitude;
coordinate->longitude = longitude;
return coordinate;
}

struct Place *create_place(char *name, double latitude, double longitude)
{
struct Place place;
place.name = name;
place.latitude = latitude;
place.longitude = longitude;
struct Place *place = (struct Place *)malloc(sizeof(struct Place));
place->name = name;
place->coordinate = create_coordinate(latitude, longitude);
return place;
}

Expand Down
10 changes: 8 additions & 2 deletions structs/c/structs.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
struct Place
struct Coordinate
{
double latitude;
double longitude;
};

struct Place
{
char *name;
struct Coordinate *coordinate;
};

struct Place create_place(char *name, double latitude, double longitude);
struct Coordinate *create_coordinate(double latitude, double longitude);
struct Place *create_place(char *name, double latitude, double longitude);

char *hello_world();
char *reverse(char *str, int length);
53 changes: 28 additions & 25 deletions structs/structs.dart
Original file line number Diff line number Diff line change
@@ -1,29 +1,5 @@
import 'dart:convert';
import 'dart:ffi' as ffi;
/*
class Place extends ffi.Struct {
@ffi.Double()
double latitude;
@ffi.Double()
double longitude;
external static int sizeOf();
@override
Place offsetBy(int offsetInBytes) => super.offsetBy(offsetInBytes).cast();
@override
Place elementAt(int index) => offsetBy(sizeOf() * index);
static Place allocate({int count: 1}) =>
ffi.allocate<ffi.Uint8>(count: count * sizeOf()).cast();
factory Place(int val) => Place.allocate()..someInt = val;
}
typedef some_Place_func = Place Function(ffi.Int32 some_int);
typedef SomePlace = Place Function(int someInt);
*/

// Example of using structs to pass strings to and from Dart/C
class Utf8 extends ffi.Struct<Utf8> {
Expand Down Expand Up @@ -53,16 +29,35 @@ class Utf8 extends ffi.Struct<Utf8> {
}
}

// Example of handling a simple C struct
class Coordinate extends ffi.Struct<Coordinate> {
@ffi.Double()
double latitude;

@ffi.Double()
double longitude;

factory Coordinate.allocate(double latitude, double longitude) =>
ffi.Pointer<Coordinate>.allocate().load<Coordinate>()
..latitude = latitude
..longitude = longitude;
}

// C string pointer return function - char *hello_world();
typedef hello_world_func = ffi.Pointer<Utf8> Function();
typedef HelloWorld = ffi.Pointer<Utf8> Function();

// C string parameter pointer function - char *reverse(char *str, int length);
// C string pointer return function - char *hello_world();
typedef reverse_func = ffi.Pointer<Utf8> Function(
ffi.Pointer<Utf8> str, ffi.Int32 length);
typedef Reverse = ffi.Pointer<Utf8> Function(ffi.Pointer<Utf8> str, int length);

// C struct pointer return function - struct Place *create_place(char *name, double latitude, double longitude);
typedef create_coordinate_func = ffi.Pointer<Coordinate> Function(
ffi.Double latitude, ffi.Double longitude);
typedef CreateCoordinate = ffi.Pointer<Coordinate> Function(
double latitude, double longitude);

main() {
final dylib = ffi.DynamicLibrary.open('structs.dylib');

Expand All @@ -77,4 +72,12 @@ main() {
final reverse = reversePointer.asFunction<Reverse>();
final reversedMessage = Utf8.fromUtf8(reverse(Utf8.toUtf8('backwards'), 9));
print('$reversedMessage');

final createCoordinatePointer = dylib
.lookup<ffi.NativeFunction<create_coordinate_func>>('create_coordinate');
final createCoordinate =
createCoordinatePointer.asFunction<CreateCoordinate>();
final coordinatePointer = createCoordinate(1.0, 2.0);
final coordinate = coordinatePointer.load();
print('Coordinate: ${coordinate.latitude}, ${coordinate.longitude}');
}

0 comments on commit 7cdbdd5

Please sign in to comment.