// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // // Dart test program for testing dart:ffi function pointers with struct // arguments. // // SharedObjects=ffi_test_functions library FfiTest; import 'dart:ffi' as ffi; import 'dylib_utils.dart'; import "package:expect/expect.dart"; import 'coordinate.dart'; import 'very_large_struct.dart'; typedef NativeCoordinateOp = Coordinate Function(Coordinate); void main() { testFunctionWithStruct(); testFunctionWithStructArray(); testFunctionWithVeryLargeStruct(); } ffi.DynamicLibrary ffiTestFunctions = dlopenPlatformSpecific("ffi_test_functions"); /// pass a struct to a c function and get a struct as return value void testFunctionWithStruct() { ffi.Pointer> p1 = ffiTestFunctions.lookup("TransposeCoordinate"); NativeCoordinateOp f1 = p1.asFunction(); Coordinate c1 = Coordinate(10.0, 20.0, null); Coordinate c2 = Coordinate(42.0, 84.0, c1); c1.next = c2; Coordinate result = f1(c1); Expect.approxEquals(20.0, c1.x); Expect.approxEquals(30.0, c1.y); Expect.approxEquals(42.0, result.x); Expect.approxEquals(84.0, result.y); c1.free(); c2.free(); } /// pass an array of structs to a c funtion void testFunctionWithStructArray() { ffi.Pointer> p1 = ffiTestFunctions.lookup("CoordinateElemAt1"); NativeCoordinateOp f1 = p1.asFunction(); Coordinate c1 = Coordinate.allocate(count: 3); Coordinate c2 = c1.elementAt(1); Coordinate c3 = c1.elementAt(2); c1.x = 10.0; c1.y = 10.0; c1.next = c3; c2.x = 20.0; c2.y = 20.0; c2.next = c1; c3.x = 30.0; c3.y = 30.0; c3.next = c2; Coordinate result = f1(c1); Expect.approxEquals(20.0, result.x); Expect.approxEquals(20.0, result.y); c1.free(); } typedef VeryLargeStructSum = int Function(VeryLargeStruct); typedef NativeVeryLargeStructSum = ffi.Int64 Function(VeryLargeStruct); void testFunctionWithVeryLargeStruct() { ffi.Pointer> p1 = ffiTestFunctions.lookup("SumVeryLargeStruct"); VeryLargeStructSum f = p1.asFunction(); VeryLargeStruct vls1 = VeryLargeStruct.allocate(count: 2); VeryLargeStruct vls2 = vls1.elementAt(1); List structs = [vls1, vls2]; for (VeryLargeStruct struct in structs) { struct.a = 1; struct.b = 2; struct.c = 4; struct.d = 8; struct.e = 16; struct.f = 32; struct.g = 64; struct.h = 128; struct.i = 256; struct.j = 512; struct.k = 1024; struct.smallLastField = 1; } vls1.parent = vls2; vls1.numChidlren = 2; vls1.children = vls1; vls2.parent = vls2; vls2.parent = null; vls2.numChidlren = 0; vls2.children = null; int result = f(vls1); Expect.equals(2051, result); result = f(vls2); Expect.equals(2048, result); vls1.free(); }