[Madrid-pm] FFI::Platypus y funciones en C++ con tipos de la STL

Joaquín Ferrero explorer en joaquinferrero.com
Dom Abr 10 14:13:02 PDT 2016


El 08/04/16 a las 22:06, Pablo Rodriguez escribió:
> Muchas gracias por intentarlo Joaquín!
>
> Si puedes compartir el código que has usado genial!
>
> Estoy pensando en transformarlo en un mini artículo para ponerlo en la web de Madrid.pm!
>

Este es código de simple_int.cpp

/*
     Ejemplo de conexión C++ <-> Perl

     Joaquín Ferrero, 2016.04.05

     g++  --shared -fkeep-inline-functions -o simple_int.so simple_int.cpp
*/

int GiveMeAnInt(void) {
     return 3;
}

Y este es el de simple_int.pl

#!/usr/bin/perl
use v5.18;
use local::lib;
use FFI::Platypus;

my $ffi = FFI::Platypus->new;
$ffi->lang('CPP');
$ffi->lib('./simple_int.so');

$ffi->attach( [ 'GiveMeAnInt()' => 'GiveMeAnInt' ] => [] => 'int');

#my $hashref = FFI::Platypus::Lang::CPP->native_type_map;
#use Data::Dumper;
#say Dumper $hashref;

my $a = GiveMeAnInt();
say "[$a]";

La clave está en definir con attach el nombre de la subrutina que recibimos desde la biblioteca compilada. g++ transforma los prototipos de las funciones en una especia de cadena de texto reducida (lo que en el manual llama mangling).

Este es el programa que no he conseguido hacer funcionar, dando una Violación de segmento

/*
     Ejemplo de conexión C++ <-> Perl

     g++ --shared -fkeep-inline-functions -o simple_str.so simple_str.cpp
*/

#include <string>

std::string
GiveMeAString(void) {
     return std::string("Perl Rocks!");
}

Y el programa en Perl:

#!/usr/bin/perl
use v5.18;
use local::lib;
use FFI::Platypus;

my $ffi = FFI::Platypus->new;
$ffi->lang('CPP');
$ffi->lib('./simple_str.so');

$ffi->attach( [ 'GiveMeAString()' => 'GiveMeAString' ] => [] => 'string');

my $a = GiveMeAString();
say $a;

Como te decía, sospecho que la violación de segmento es por tema de punteros o memoria no reservada. Quizás STL no sea capaz de mandar el puntero de la cadena de caracteres hacia Perl.

Quizás se pueda hacer con lo que se comenta en el manual, con lo de "extern C * char", pero lo dudo.

Quizás, también, es que los únicos tipos que se pueden pasar son los que aparecen en el método native_type_map()

Lo que sí funciona es el ejemplo orientado a objetos que aparece en la sinopsis o en la carpeta de ejemplos de la distribución.

Por mucho que he buscado, no he encontrado ejemplos con la STL. Habría que escribir una carta al autor de la distribución, a ver si nos da una pista. Seguro que tiene que ser algo de FFI::Platypus que se nos ha escapado.

JF



Más información sobre la lista de distribución Madrid-pm