I have a basic FFI call that retrieves a C struct from Dart. Only the char *
and int *
fields of the struct are returning proper values. The float *
and int
are returning the wrong values. The C and Dart code is below along with the output.
If I were to print the two bad types out on the C side, they do yield proper values.
C Code
// C code
typedef struct {
float * floatPtr;
int count;
char * name;
int * intPtr;
}baseStruct;
baseStruct getMyStruct(){
static baseStruct myStruct;
static int someint = 22;
static float foo [] = {0.1, 0.2, 0.3};
myStruct.floatPtr = foo;
myStruct.count = 0;
myStruct.intPtr = &someint;
myStruct.name = "some string";
return myStruct;
}
Dart Code
// Dart Type for C struct
class MyStructType extends Struct {
external Pointer<Float> floatPtr;
@Int32()
external int count;
external Pointer<Int> intPtr; //worked
external Pointer<Utf8> name; //worked
}
// type defs for FFI
typedef GetMyStructNative = MyStructType Function();
typedef GetMyStruct = MyStructType Function();
// Code to call function from dynamic library
static final getMyStruct = module
.lookupFunction<GetMyStructNative, GetMyStruct>('getMyStruct');
// call native function and get native struct
MyStructType myStruct = getMyStruct();
/***************************** OUTPUT *************************/
final count = myStruct.count;
print("count: $count"); // prints some big number like 475423 that's not 0 (incorrect)
final intPtr = myStruct.intPtr.value;
print("count: $intPtr"); // prints 22 (correct)
final name = myStruct.name.toDartString();
print("name: $name"); // prints 'some string' (correct)
final floatPtr myStruct.floatPtr.asTypedList(3);
print("floatPtr: $floatPtr"); // prints [0.0, 0.0, 4.764414778704378e-44] (incorrect)
Got this answer from @blaugold on github. The order of the fields in the structs must match. So changing the dart struct as below fixes the problem.
class MyStructType extends Struct {
external Pointer<Float> floatPtr;
// Int32 -> Int
@Int()
external int count;
// The order of fields matters, so `name` and `intPtr` need to be flipped.
external Pointer<Utf8> name;
external Pointer<Int> intPtr;
}