Passing function pointer to fcall

wp1068189-ssc stefan.sonnenberg@pythonmeister.com
Sun Nov 27 07:33:00 GMT 2011


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
>
>



More information about the Libffi-discuss mailing list