This is the mail archive of the
libffi-discuss@sourceware.org
mailing list for the libffi project.
Re: Passing function pointer to fcall
So, I extended the program some more:
#include <stdio.h>
#include <ffi.h>
#include <stdlib.h>
#include <windows.h>
int add(int a,int b, char *fmt,void *fn) {
// int (*func)(char *,int) = (int (*)(char
*,int))GetProcAddress(GetModuleHandle("msvcrt.dll"),fn);
int (*func)(char *,int) = (int (*)(char *,int))fn;
return func(fmt,a+b);
}
int main(void)
{
ffi_cif cif;
ffi_abi abi;
ffi_status status;
int nargs = 4;
ffi_type *rtype = &ffi_type_sint32;
ffi_type *atypes[4];
void *avalues[4];
int result;
int a,b;
a = 3;
b = 4;
char *fmt = "The answer is %i\n";
char *fn = "printf";
atypes[0] = &ffi_type_sint32;
atypes[1] = &ffi_type_sint32;
atypes[2] = &ffi_type_pointer;
atypes[3] = &ffi_type_pointer;
avalues[0] = malloc(atypes[0]->size);
avalues[1] = malloc(atypes[1]->size);
*(int *) avalues[0] = a;
*(int *) avalues[1] = b;
avalues[2] = (char *) &fmt;
avalues[3] = &printf;
printf("direct call: %i",add(3,4,"erg: %i\n",&printf));
status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rtype, atypes);
if(status != FFI_OK)
printf("ffi_prep_cif failed (%i)\n",status);
// crash occurs somewhere near here ...
ffi_call(&cif,FFI_FN(add),&result,avalues);
printf("%i\n",result);
return 0 ;
}
As you can see, I call my add function twice, once directly
and once via ffi_call.
Both times I pass a reference to printf.
As the direct method works, I guess the principal code is OK.
Now, when I run the program it shows:
$ dyn_callback.exe
erg: 7
direct call: 7
Then it crashes and creates this callstack:
dyn_callback.exe caused an Access Violation at location 614c25ff Reading
from location 614c25ff.
Registers:
eax=614c25ff ebx=0040138c ecx=00000000 edx=00000003 esi=45206472 edi=6085db86
eip=614c25ff esp=0022fe34 ebp=0022fe60 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
Call stack:
AddrPC AddrReturn AddrFrame AddrStack Params
614C25FF 004013AF 0022FE30 0022FE34 00403064 00000007 77C35C94
77C12580
614C25FF
004013AF 6B746957 0022FE60 0022FE34 00000003 00000004 00403064
614C25FF
004013AF dyn_callback.exe:004013AF add dyn_callback.c:10
...
int (*func)(char *,int) = (int (*)(char *,int))fn;
return func(fmt,a+b);
> }
int main(void)
...
6B746957 6B7465AF 0022FE78 0022FE34 6B746298 0022FEB4 00000010
00000001
6B746957 libffi-6.dll:6B746957 ffi_call_win32
6B7465AF 004014FB 0022FEC8 0022FE34 0022FF20 0040138C 0022FEFC
0022FF00
6B7465AF libffi-6.dll:6B7465AFC:\MinGW\msys\1.0\local\bin\libffi-6.dll:
No symbol found
ffi_call
004014FB 004010B9 0022FF58 0022FE34 00000001 005B2C98 005B2ED0
00405004
004014FB dyn_callback.exe:004014FB main dyn_callback.c:53
...
ffi_call(&cif,FFI_FN(add),&result,avalues);
> printf("%i\n",result);
return 0 ;
...
004010B9 00401284 0022FFA0 0022FE34 00000001 A47CBD08 7C90DCBA
7C817064
004010B9 dyn_callback.exe:004010B9 __mingw_CRTStartup crt1.c:244
00401284 7C817067 0022FFC0 0022FE34 6085DB86 45206472 7FFDA000
C0000005
00401284 dyn_callback.exe:00401284 WinMainCRTStartup crt1.c:274
7C817067 00000000 0022FFF0 0022FE34 0040126C 00000000 00000000
00000000
7C817067 kernel32.dll:7C817067
C:\WINDOWS\system32\kernel32.dll: No symbols
RegisterWaitForInputIdle
DEBUG_EVENT:
dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT
dwProcessId = CCC
dwThreadId = A30
dwExitCode = C0000005
I installed libffi 3.0.11 beforhand, but sadly it produces no debugging
symbols.