Pasando C ++ puntero estructura de Perl para arbitraria llamada de función DLL
-
13-09-2019 - |
Pregunta
Estoy utilizando Win32 :: API para llamar a una función arbitraria exportada en un archivo DLL que acepta un puntero de C ++ estructura.
struct PluginInfo {
int nStructSize;
int nType;
int nVersion;
int nIDCode;
char szName[ 64 ];
char szVendor[ 64 ];
int nCertificate;
int nMinAmiVersion;
};
Como tenemos que utilizar la función de "paquete" para la construcción de la estructura y la necesidad de pasar un argumento
my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);
No es la construcción de la estructura adecuada.
Parece que el argumento de longitud aplicada a C engullirá los muchos argumentos.
¿Puede alguien por favor sugerir la mejor manera de construir esta estructura de forma Perl y passon a la llamada DLL.
Gracias de antemano, España Naga Kiran
Solución
Uso Z
(cadena NUL) en su plantilla, como en
my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);
Además, echar un vistazo a Win32::API::Struct
, que forma parte del módulo de Win32 :: API.
Otros consejos
Para cualquier cosa complicada, echa un vistazo a Convertir :: :: binario C . Puede parecer intimidante al principio, pero una vez que te das cuenta de su poder, que es un abridor de ojos.
Actualización: Quiero añadir un poco de información. Es necesario tener un vistazo a una sección específica de la página de manual del módulo para la principal razón para usarlo. Voy a citar por conveniencia:
¿Por qué utilizar Convert :: :: binario C?
Digamos que quiere embalar (o descomprimir) de datos según la siguiente C estructura:
struct foo {
char ary[3];
unsigned short baz;
int bar;
};
Se podría, por supuesto, utilizar el paquete de Perl y desempaquetar funciones:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
Pero esto implica que la estructura miembros están alineados byte. Si fueran largo alineado (que es el valor predeterminado para la mayoría de los compiladores), que tendría que escribir
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
que en realidad no aumentar legibilidad.
Ahora imagine que usted necesita para empacar la datos para un completamente diferente arquitectura con diferentes bytes orden. Que se vería en el paquete página de manual venir de nuevo y tal vez con esto:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
Sin embargo, si se intenta descomprimir $ foo de nuevo, sus valores con signo se han convertido en otras más sin firmar.
Todo esto todavía se puede manejar con Perl. Pero imaginan sus estructuras consiguen ¿mas complejo? Imagínese que usted necesita apoyar diferentes plataformas? Imagina es necesario hacer cambios en el estructuras? Usted no sólo tiene que cambiar la fuente de C sino también docenas de cadenas de carga en su código Perl. Esta no es divertido. Y Perl debe ser divertido.
Ahora, ¿no sería estupendo si pudiera acabo de leer en el código fuente en C que has ya escrito y utilizar todos los tipos no definido para el embalaje y desembalaje? Eso es lo :: :: convertir binario C hace.