Passando C puntatore struttura ++ da Perl arbitrariamente chiamata di funzione dll
-
13-09-2019 - |
Domanda
Sto usando Win32 :: API per chiamare una funzione arbitraria esportata in una DLL che accetta un puntatore struttura di C ++.
struct PluginInfo {
int nStructSize;
int nType;
int nVersion;
int nIDCode;
char szName[ 64 ];
char szVendor[ 64 ];
int nCertificate;
int nMinAmiVersion;
};
Come abbiamo bisogno di utilizzare la funzione "pacco" per costruire la struttura e la necessità di passare un argomento
my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);
La sua non è costruire la struttura in modo corretto.
Sembra che l'argomento lunghezza applicato alla C sarà inghiottire quei tanti argomenti.
qualcuno può per favore suggerire il modo migliore per costruire tale struttura modulo Perl e Passon alla chiamata dll.
Grazie in anticipo,
Naga Kiran
Soluzione
Usa Z
(stringa NUL imbottito) nel modello, come in
my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);
Inoltre, dare un'occhiata a Win32::API::Struct
, che fa parte del modulo API Win32 ::.
Altri suggerimenti
Per quanto complicata, controllare Convertire :: :: binario C . Può sembrare scoraggiante in un primo momento, ma una volta che ci si rende conto il suo potere, è un aprire gli occhi.
Aggiornamento: Mi permetto di aggiungere un po 'di informazioni. È necessario avere uno sguardo ad un specifica sezione del modulo manpage per la ragione principale per usarlo. Citerò per comodità:
Perché usare Convert :: :: binario C?
dire che si desidera mettere in valigia (o disfare) i dati secondo il seguente C struttura:
struct foo {
char ary[3];
unsigned short baz;
int bar;
};
Si potrebbe ovviamente usare pacchetto di Perl e le funzioni di decomprimere:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
Ma questo implica che la struct membri sono allineati byte. Se fossero lungo allineati (che è il default per maggior parte dei compilatori), che avrebbe dovuto scrivere
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
che in realtà non aumenta leggibilità.
Ora immaginate che è necessario mettere in valigia il dati per un completamente diverso architettura con diversi byte ordine. Si potrebbe esaminare il pacco pagina di manuale di nuovo e magari venire con in questo modo:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
Tuttavia, se si tenta di decomprimere $ pippo ancora una volta, i tuoi valori con segno hanno trasformato in quelle non firmate.
Tutto questo può ancora essere gestito con Perl. Ma immaginate vostre strutture ottengono più complesso? Immaginate è necessario supportare diverse piattaforme? Immaginare è necessario apportare modifiche al strutture? Non sarà sufficiente modificare la sorgente C ma anche decine di stringhe pacchetto nel codice Perl. Questo non è divertente. E Perl dovrebbe essere divertente.
Ora, non sarebbe bello se si potesse appena letto nel sorgente C che hai già scritto e utilizzare tutti i tipi ci definito per imballaggio e disimballaggio? Questo è ciò che Convert :: :: binario C fa.