libffi

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

libffi

Beitrag von Xin » Mo Dez 10, 2012 11:29 am

Moin zusammen,

Hat sich jemand bereits mit der libffi auseinandergesetzt?

Unter Windows habe ich sie bisher noch nicht ans Laufen bekommen, unter Linux bekomme ich das Beispielprogramm nichtmals freiwillig durch den Compiler. Nach einer kleiner Anpassung sieht das Beispielprogramm so aus:

Code: Alles auswählen

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

int main()
{
  ffi_cif cif;
  ffi_type *args[1];
  void *values[1];
  char const *s;
  int rc;
  
  typedef void (*func)( void );                       // hinzugefügt
  
  /* Initialize the argument info vectors */    
  args[0]   = &ffi_type_pointer;
  values[0] = &s;
  
  func funcptr = reinterpret_cast< func >( puts );          //hinzugefügt
  
  /* Initialize the cif */
  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
                   &ffi_type_uint, args) == FFI_OK)
    {
      s = "Hello World!";
      ffi_call(&cif, funcptr, &rc, values);                 // puts nach funcptr getauscht
      /* rc now holds the result of the call to puts */
      
      printf( "rc: %d\n", rc );
      
      /* values holds a pointer to the function's arg, so to 
         call puts() again all we need to do is change the 
         value of s */
//      s = "This is cool!";
      ffi_call(&cif, funcptr, &rc, values);                 // puts  nach funcptr getauscht
      printf( "rc: %d\n", rc );
    }
  
  return 0;
}
und ich erhalte folgendes:

Code: Alles auswählen

xin@trinity:~/xsd/try/ffi_ubuntu$ valgrind ./a.out 
==6316== Memcheck, a memory error detector
==6316== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6316== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6316== Command: ./a.out
==6316== 
Hello World!
rc: 13
==6316== Invalid read of size 8
==6316==    at 0x4E374A2: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.6.0.0)
==6316==    by 0x4009A2: main (in /home/xin/xsd/try/ffi_ubuntu/a.out)
==6316==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==6316== 
...
Mit anschließendem Segmentation Fault.

Der erste Aufruf funktioniert, der zweite hingegen fliegt mir um die Ohren.

Code: Alles auswählen

xin@trinity:~/xsd/try/ffi_ubuntu$ uname -a
Linux trinity 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:31:23 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: libffi

Beitrag von Xin » Mo Dez 10, 2012 1:57 pm

Code: Alles auswählen

 int rc;
ist der Übeltäter.

An dem Code musste ich ja bereits einiges ändern, damit er durch meinen Compiler rennt. Auf einem 32-Bit-System läuft der Code auch... wenn auch nicht bei mir, denn wie im anderen Thread beschrieben, bekomme ich die 32-Bit Version nicht zusammenkompiliert. (Ein erfolgreicher Tag also...)

Puts scheint auf 64-Bit Systemen ein 64 Bit Interger zurück zu geben - kann das mal einer Bestätigen!? Es wäre ja logisch, aber bisher habe ich noch keine Bestätigung dazu bekommen. Die Variable rc ist aber int (32 Bit).
Um das kompatibel zu halten nehme man den Datentyp ffi_arg:

Code: Alles auswählen

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

void show( ffi_cif const & cif )
{
    printf( "abi %x\n", cif.abi);
    printf( "nargs %x\n", cif.nargs);
    printf( "bytes %x\n", cif.bytes);
    printf( "flags %x\n", cif.flags);
#ifdef FFI_EXTRA_CIF_FIELDS
    printf( "extra fields\n");
#endif
}


int main()
{
  ffi_cif cif;
  ffi_type *args[1];
  void *values[1];
  char const *s;
  ffi_arg rc;
  
  typedef void (*func)( void );
  
  /* Initialize the argument info vectors */    
  args[0]   = &ffi_type_pointer;
  values[0] = &s;
  
  func funcptr = reinterpret_cast< func >( puts );
  /*
typedef struct {
  ffi_abi abi;
  unsigned nargs;
  ffi_type **arg_types;
  ffi_type *rtype;
  unsigned bytes;
  unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS
  FFI_EXTRA_CIF_FIELDS;
#endif
} ffi_cif;
*/
  /* Initialize the cif */
  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
                   &ffi_type_uint, args) == FFI_OK)
    {
      s = "Hello World!";
      ffi_call(&cif, funcptr, &rc, values);
      /* rc now holds the result of the call to puts */
      
      printf( "rc: %d\n", rc );
      
      /* values holds a pointer to the function's arg, so to 
         call puts() again all we need to do is change the 
         value of s */
    printf( "2.\n" );
      s = "This is cool!";

      ffi_call(&cif, funcptr, &rc, values);
      printf( "rc: %d\n", rc );
    }
  
  return 0;
}
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Orioner
Beiträge: 102
Registriert: Mo Dez 10, 2012 10:52 am

Re: libffi

Beitrag von Orioner » Do Dez 13, 2012 9:43 am

Ich kann das nicht bestätigen, aber was ich sagen kann, ist, dass eine Integervariable auf einem 64-Bit-System 64 Bit und nicht 32 Bit hat. Hilft das?

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: libffi

Beitrag von Xin » Do Dez 13, 2012 7:03 pm

Orioner hat geschrieben:Ich kann das nicht bestätigen, aber was ich sagen kann, ist, dass eine Integervariable auf einem 64-Bit-System 64 Bit und nicht 32 Bit hat. Hilft das?
Es gibt die Vermutung, dass was auch immer als Ergebnis zurückkommt auf ein 64-Bit int gecastet wird, dass dann an die Ergebnisvariable geschrieben wird.

Ansonsten ist "int" "mindestens" 32 Bit - und üblicherweise auch auf 64 Bittern auch nur 32 Bit groß. Für ein 64 Bit-int sollte man eher long int.anfordern.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten