Passing C ++ Struktur Zeiger von Perl auf beliebigen dll Funktionsaufruf
-
13-09-2019 - |
Frage
Ich bin mit Win32 :: API eine willkürliche Funktion in einer DLL exportiert rufen, die eine C ++ Struktur Zeiger akzeptiert.
struct PluginInfo {
int nStructSize;
int nType;
int nVersion;
int nIDCode;
char szName[ 64 ];
char szVendor[ 64 ];
int nCertificate;
int nMinAmiVersion;
};
Wie wir brauchen die „Pack“ Funktion verwenden, um die Struktur zu konstruieren und brauchen ein Argument zu übergeben
my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);
Es ist nicht die Struktur der Konstruktion richtig.
Es scheint, dass die Länge Argument C angewendet wird, diese viele Argumente verschlingen.
Kann jemand bitte die beste Art und Weise legt nahe, diese Struktur Form Perl und passon zu DLL-Aufruf zu konstruieren.
Vielen Dank im Voraus,
Naga Kiran
Lösung
Mit Z
(NUL-gepolstertem string) in der Vorlage, wie in
my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);
Werfen Sie auch einen Blick auf Win32::API::Struct
, das ist Teil der API-Modul :: Win32.
Andere Tipps
Für etwas kompliziert Besuche Convert :: Binary :: C . Es mag auf den ersten entmutigend, aber wenn man seine Macht erkennen, es ist ein Augenöffner.
Update: Lassen Sie mich ein paar Informationen hinzuzufügen. Sie müssen in einem bestimmter Abschnitt der Manpage des Moduls für den Hauptgrund dafür, es zu benutzen. Ich werde es der Einfachheit halber zitiere:
Warum Verwendung Convert :: Binary :: C?
Angenommen, Sie verpacken möchten (oder entpacken) Daten nach dem folgenden C Struktur:
struct foo {
char ary[3];
unsigned short baz;
int bar;
};
Sie könnten natürlich verwenden Perl Pack und entpacken Funktionen:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
Aber dies bedeutet, dass die Struktur Mitglieder Byte ausgerichtet ist. Wenn sie wären lang ausgerichtet (das ist der Standard für die meisten Compiler), dann würden Sie schreiben
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
, die nicht wirklich erhöhen Lesbarkeit.
Nun stell dir vor, dass Sie die Notwendigkeit zu packen Daten für eine völlig andere Architektur mit unterschiedlichen Byte Bestellung. Sie würde sich in die Packung manpage wieder und vielleicht kommen mit folgt aus:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
Wenn Sie jedoch versuchen, $ foo zu entpacken wieder haben Ihre Werte mit Vorzeichen gedreht in unsigned diejenigen.
All dies kann noch mit verwaltet werden Perl. Aber stellen Sie Ihre Strukturen erhalten komplexer? Stellen Sie sich vor Sie müssen unterstützt verschiedene Plattformen? Vorstellen Sie müssen Änderungen an der machen Strukturen? Sie werden nicht nur auf Ändern Sie die C-Quelle, sondern auch Dutzende von Pack Strings in Ihrem Perl-Code. Diese kein Spaß ist. Und Perl soll Spaß machen.
Nun wäre es nicht toll, wenn Sie könnten nur lesen Sie in der C-Quelle haben bereits geschrieben und alle Typen verwenden definiert es für die Verpackung und Auspacken? Das ist, was Convert :: Binary :: C der Fall ist.