This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Passing function pointer to fcall


Hi,

I was not a type, it was by intention.
The code looked originally so:

#include<stdio.h>
#include<ffi.h>
#include<stdlib.h>

int msg(void (*a) (char *)) {
ÂÂÂÂ a("Hi, there !\n");
ÂÂÂÂ return 23;
}
int main(int argc, char ** argv)
ÂÂÂÂ {
ÂÂÂÂ ffi_cif cif;
ÂÂÂÂ ffi_abi abi;
ÂÂÂÂ ffi_status status;
ÂÂÂÂ int nargs = 1;
ÂÂÂÂ ffi_type *rtype =&ffi_type_uint32;
ÂÂÂÂ ffi_type **atypes;
ÂÂÂÂ void **avalues;
ÂÂÂÂ void *result;

ÂÂÂÂ atypes = malloc(sizeof(ffi_type));

ÂÂÂÂ atypes[0] =&ffi_type_pointer;
ÂÂÂÂ avalues = malloc(sizeof(ffi_type_pointer));

ÂÂÂÂ // I want to call msg with a pointer to printf

ÂÂÂÂ *(void**)avalues[0] = printf;
ÂÂÂÂ status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rtype, atypes);
ÂÂÂÂ result = (ffi_type *) malloc(sizeof(rtype->size));

ÂÂÂÂ if(status != FFI_OK)
ÂÂÂÂÂÂÂÂ printf("ffi_prep_cif failed (%i)\n",status);

ÂÂÂÂÂ ffi_call(&cif,FFI_FN(msg),result,avalues);
ÂÂÂÂÂ return(*(int *)result);
ÂÂÂÂÂ }

I'm on Windows XP SP2, with mingw:
gcc -v
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.6.1/lto-wrapper.exe
Ziel: mingw32
Konfiguriert mit: ../gcc-4.6.1/configure
--enable-languages=c,c++,fortran,objc,obj-c++ --disable-sjlj-exceptions --with-
dwarf2 --enable-shared --enable-libgomp --disable-win32-registry
--enable-libstdcxx-debug --enable-version-specific-runt
ime-libs --build=mingw32 --prefix=/mingw
Thread-Modell: win32
gcc-Version 4.6.1 (GCC)

libffi is 3.0.10 build and installed with ./configure && make && make install

The example above is compiled this way:

gcc dyn_callback.c libffi-5.dll -I /lib/libffi-3.0.10/include/ -o dyn_callback

On your suggestion I changed the code a bit, so that result get alloc'd this
way:

result = (ffi_type *) malloc(long);

Simple: if I execute the program, nothing happens.
If I comment out the line

ÂÂÂÂ a("Hi, there !\n");

I get back 23 by $? after execution.
If it is there, I get 5.

I'm stuck.


Anthony Green <green@moxielogic.com> hat am 27. November 2011 um 05:05
geschrieben:

> On 11/26/2011 7:05 PM, wp1068189-ssc wrote:
> > Please take a look at this piece of code:
> >Â Â
> > #include<stdio.h>
> > #include<ffi.h>
> > #include<stdlib.h>
> >
> > int msg(void (*a) (char *)) {
> >Â Â Â return 23;
> >Â Â Â // but this doesn't work :-(
> >Â Â Â a("Hi, there !\n");
> > }
> >
> > int main(int argc, char ** argv)
> >Â Â Â {
> >
> >
> >Â Â Â ffi_cif cif;
> >Â Â Â ffi_abi abi;
> >Â Â Â ffi_status status;
> >Â Â Â int nargs = 1;
> >Â Â Â ffi_type *rtype =&ffi_type_uint32;
> >Â Â Â ffi_type **atypes;
> >Â Â Â void **avalues;
> >Â Â Â void *result;
> >
> >Â Â Â atypes = malloc(sizeof(ffi_type));
> >Â Â Â atypes[0] =&ffi_type_pointer;
> >
> >Â Â Â avalues = malloc(sizeof(ffi_type_pointer));
> >Â Â Â // I want to call msg with a pointer to printf
> >Â Â Â *(void**)avalues[0] = printf;
> >
> >Â Â Â status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, nargs, rtype, atypes);
> >
> >Â Â Â result = (ffi_type *) malloc(sizeof(rtype->size));
> >
> >Â Â Â if(status != FFI_OK)
> >Â Â Â Â Â printf("ffi_prep_cif failed (%i)\n",status);
> >
> >Â Â Â ffi_call(&cif,FFI_FN(msg),result,avalues);
> >
> >Â Â Â return(*(int *)result);
> >Â Â Â }
> >Â Â
> > As you might imagine, I'd like to call a function "msg" and send it a
> > pointer to
> > printf,
> > but that does not work.
> > I guess it has to do with the pointer me is constructing.
> >Â Â
> > But I have absolutely no idea what I'm doing wrong.
> >Â Â
> > Can anyone help, please ?
>
>
> Let's get the obvious one of out the way... you are returning from msg()
> before calling the function.
>
> I'm going to assume that's a typo or something.
>
> What platform are you working on? Also, you should declare "a" in msg()
> to have the same prototype as printf.
>
> Also, there's an oddity in the libffi API, and that is that "result"
> needs to be the largest native integral type on your system. So, use a
> long for result instead of mallocing the exact return type size. You
> can pass it into ffi_call as &result and simply cast it to an int at the
> end.
>
> Anthony Green
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]