Forgive me if this is already a known issue or if I'm missing something, though I couldn't find any obvious reference to it. I ran across this issue via running the test suite for Python on Cygwin 64-bit. The following simple example reproduces the problem:
#include <ffi.h>
#include <stdio.h>
#include <assert.h>
typedef struct {
unsigned long first;
unsigned long second;
unsigned long third;
} Test;
static void update_value(Test in) {
((volatile Test*)&in)->first = 0x0badf00d;
((volatile Test*)&in)->second = 0x0badf00d;
((volatile Test*)&in)->third = 0x0badf00d;
}
int main(void) {
ffi_cif cif;
ffi_type *args[1];
void *values[1];
ffi_type Test_type;
ffi_type *Test_type_elements[4];
int idx;
Test test = {0xdeadbeef, 0xcafebabe, 0x0bad1dea};
Test_type.size = Test_type.alignment = 0;
Test_type.elements = (ffi_type **)&Test_type_elements;
for (idx = 0; idx < 3; idx++) {
Test_type_elements[idx] = &ffi_type_ulong;
}
Test_type_elements[3] = NULL;
args[0] = &Test_type;
values[0] = (void*)&test;
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_void, args) == FFI_OK) {
ffi_call(&cif, (void*)update_value, NULL, values);
printf("test.first = 0x%08lx\n", test.first);
assert(test.first == 0xdeadbeef);
} else {
printf("Error with ffi_prep_cif\n");
}
return 0;
}
Just looking at ffiw64.c I think it's pretty simplistic--it always just passes struct types by reference, and doesn't make a copy first before a pass by value.
Forgive me if this is already a known issue or if I'm missing something, though I couldn't find any obvious reference to it. I ran across this issue via running the test suite for Python on Cygwin 64-bit. The following simple example reproduces the problem:
Just looking at ffiw64.c I think it's pretty simplistic--it always just passes struct types by reference, and doesn't make a copy first before a pass by value.