add a simple ffi test using structs

This commit is contained in:
Bennet Bleßmann
2025-02-17 19:58:46 +01:00
committed by Bennet Bleßmann
parent 760e1d2aac
commit 6205f2f1f1
2 changed files with 71 additions and 0 deletions

19
tests-pl/ffi_struct.pl Normal file
View File

@@ -0,0 +1,19 @@
:- use_module(library(os)).
:- use_module(library(ffi)).
test :-
read(Body),
term_variables(Body, [LIB]),
Body,
foreign_struct(pg, [uint8, uint16, uint32, uint64, uint8, f32, f64]),
use_foreign_module(LIB, ['construct'([uint8, uint16, uint32, uint64, uint8, f32, f64], pg), 'modify'([pg], pg)]),
ffi:'construct'(8, 12, 46, 40, 127, 1.368, -4.587, PG),
write(("PG"-PG)), nl,
ffi:'modify'(PG, [pg, A, B, C, D, A2, E, F]),
% skipping E & F for now as the result changes between runs for some reason
write(("PG2"-[pg, A, B, C, D, A2, "skip", "skip"])), nl,
% avoide singelton warning
E = _,
F = _.
:- initialization(test).

View File

@@ -194,3 +194,55 @@ fn ffi_invalid_type() {
"% Warning: initialization/1 failed for: user:test\n", "% Warning: initialization/1 failed for: user:test\n",
); );
} }
#[test]
#[cfg_attr(miri, ignore = "ffi")]
fn ffi_struct() {
let dynlib_path = build_dynamic_library(
"ffi_struct",
r##"
#[repr(C)]
struct PaddingGalore {
a: u8,
b: u16,
c: u32,
d: u64,
a2: u8,
e: f32,
f: f64,
}
#[no_mangle]
extern "C" fn construct(a: u8, b: u16, c: u32, d: u64, a2: u8, e: f32, f: f64) -> PaddingGalore {
PaddingGalore {
a,
a2,
b,
c,
d,
e,
f,
}
}
#[no_mangle]
extern "C" fn modify(data: PaddingGalore) -> PaddingGalore {
PaddingGalore {
a: data.a2,
a2: data.a,
b: !data.b,
c: !data.c,
d: !data.d,
e: -data.e,
f: -data.f,
}
}
"##,
);
load_module_test_with_input(
"tests-pl/ffi_struct.pl",
format!("LIB={dynlib_path:?}."),
"[P,G]-[pg,8,12,46,40,127,1.3680000305175781,-4.587]\n[P,G,2]-[pg,127,65523,4294967249,18446744073709551575,8,[s,k,i,p],[s,k,i,p]]\n",
);
}