blob: a164e4443575b6cdfd3bfd65a27e7980f4354715 [file] [log] [blame] [edit]
// Copyright (c) 2024, 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.
// SharedObjects=ffi_test_functions
// @dart=3.5
import 'dart:ffi';
import 'dart:typed_data';
import 'package:expect/expect.dart';
import 'dylib_utils.dart';
// In both below native methods, the expecting parameters are
// SumFirstTwoElements(Pointer<Array<Int32>> (which is also Pointer<Int32>))
// SumTwoElements(a: Pointer<Int32>, b: Pointer<Int32)
// but we are intentionally setting to
// Pointer<Void> to test .address.cast()
@Native<Int32 Function(Pointer<Void>)>(
symbol: "SumFirstTwoElements", isLeaf: true)
external int sumFirstTwoElements(Pointer<Void> a);
@Native<Int32 Function(Pointer<Void>, Pointer<Void>)>(
symbol: "SumTwoPointers", isLeaf: true)
external int sumTwoPointers(Pointer<Void> a, Pointer<Void> b);
void testStructField() {
final myStruct = Struct.create<MyStruct>();
myStruct.arr1[0] = 3424;
myStruct.arr2[1] = 1000;
final expectedArr1 = myStruct.arr1[0] + myStruct.arr1[1];
final arr1SumFirstTwoElements =
sumFirstTwoElements(myStruct.arr1.address.cast());
Expect.equals(arr1SumFirstTwoElements, expectedArr1);
final arr1SumTwoPointers = sumTwoPointers(
myStruct.arr1[0].address.cast(), myStruct.arr1[1].address.cast());
Expect.equals(arr1SumTwoPointers, expectedArr1);
myStruct.arr2[0] = 10;
myStruct.arr2[1] = 100001;
final expectedArr2 = myStruct.arr2[0] + myStruct.arr2[1];
final arr2SumFirstTwoElements =
sumFirstTwoElements(myStruct.arr2.address.cast());
Expect.equals(arr2SumFirstTwoElements, expectedArr2);
final arr2SumTwoPointers = sumTwoPointers(
myStruct.arr2[0].address.cast(), myStruct.arr2[1].address.cast());
Expect.equals(arr2SumTwoPointers, expectedArr2);
myStruct.value1 = 22;
myStruct.value2 = 3222;
final expectedStructValueSum = myStruct.value1 + myStruct.value2;
final structValueSumTwoPointers = sumTwoPointers(
myStruct.value1.address.cast(), myStruct.value2.address.cast());
Expect.equals(structValueSumTwoPointers, expectedStructValueSum);
}
void testUnionField() {
final myUnion = Union.create<MyUnion>();
myUnion.arr[0] = 23422;
myUnion.arr[1] = 231312;
final expected = myUnion.arr[0] + myUnion.arr[1];
final arrSumFirstTwoElements =
sumFirstTwoElements(myUnion.arr.address.cast());
Expect.equals(arrSumFirstTwoElements, expected);
final arrSumTwoPointers = sumTwoPointers(
myUnion.arr[0].address.cast(), myUnion.arr[1].address.cast());
Expect.equals(arrSumTwoPointers, expected);
myUnion.value1 = 234522;
myUnion.value2 = 3322542;
final expectedStructValueSum = myUnion.value1 + myUnion.value2;
final structValueSumTwoPointers = sumTwoPointers(
myUnion.value1.address.cast(), myUnion.value2.address.cast());
Expect.equals(structValueSumTwoPointers, expectedStructValueSum);
}
void testTypedData() {
final buffer = Int32List.fromList([34241, 42432, 42313]);
final expected = buffer[0] + buffer[1];
final bufferSumFirstTwoElements = sumFirstTwoElements(buffer.address.cast());
Expect.equals(bufferSumFirstTwoElements, expected);
final bufferSumFirstTwoPointers =
sumTwoPointers(buffer[0].address.cast(), buffer[1].address.cast());
Expect.equals(bufferSumFirstTwoPointers, expected);
}
void main() {
dlopenGlobalPlatformSpecific("ffi_test_functions");
testStructField();
testTypedData();
testUnionField();
}
final class MyStruct extends Struct {
@Int32()
external int value1;
@Int32()
external int value2;
@Array<Int32>(2)
external Array<Int32> arr1;
@Array<Int32>(2)
external Array<Int32> arr2;
}
final class MyUnion extends Union {
@Int32()
external int value1;
@Int32()
external int value2;
@Array<Int32>(2)
external Array<Int32> arr;
}