Question

J'utilise Win32 :: API pour appeler une fonction exportée dans une arbitraire DLL qui accepte un pointeur de structure C ++.

struct PluginInfo {
        int  nStructSize;   
        int  nType;     
        int  nVersion;    
        int  nIDCode;    
        char         szName[ 64 ];  
        char            szVendor[ 64 ];
        int  nCertificate;  
        int  nMinAmiVersion;
};

Comme nous avons besoin d'utiliser la fonction « pack » pour construire la structure et la nécessité de passer un argument

my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);

Ce ne est pas la construction de la structure correctement.
Il semble que l'argument de longueur appliquée à C gobe ces nombreux arguments.
Quelqu'un peut s'il vous plaît suggérer la meilleure façon de construire cette structure forme Perl et passon à l'appel dll.

Merci à l'avance,
Naga Kiran

Était-ce utile?

La solution

Utilisez Z (string NUL rembourré) dans votre modèle, comme dans

my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);

De plus, jetez un oeil à Win32::API::Struct , qui fait partie du module API Win32.

Autres conseils

Pour tout compliqué, consultez Convert :: Binary :: C . Il peut sembler intimidant au début, mais une fois que vous vous rendez compte de son pouvoir, il est ouvert les yeux.

Mise à jour: Permettez-moi d'ajouter un peu d'information. Vous devez avoir un coup d'oeil à section spécifique manpage du module pour la raison principale de l'utiliser. Je vais le citer pour des raisons pratiques:

Pourquoi utiliser Convert :: Binary :: C?

  

Dites que vous voulez emballer (ou déballer) données   en fonction du C suivant   structure:

struct foo {
  char ary[3];
  unsigned short baz;
  int bar;
};
  

Vous pouvez bien sûr utiliser le pack Perl   et déballer les fonctions:

@ary = (1, 2, 3);
$baz = 40000;  
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
  

Mais cela implique que la struct   sont alignés octet membres. Si elles étaient   longue alignés (qui est la valeur par défaut pour   la plupart des compilateurs), vous devriez écrire

 $binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
  

qui n'augmente pas vraiment   lisibilité.

     

Maintenant, imaginez que vous devez emballer le   données pour un tout autre   l'architecture avec différents octets   ordre. Vous regardez dans le pack   et peut-être à nouveau manpage venir avec   ceci:

$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
  

Cependant, si vous essayez de déballer $ foo   encore une fois, vos valeurs signées ont tourné   dans les non signés.

     

Tout cela peut encore être géré avec   Perl. Mais imaginez vos structures se   plus complexe? Imaginez que vous devez   soutenir différentes plates-formes? Imaginer   vous devez apporter des modifications à la   structures? Vous aurez non seulement à   changer la source de C mais aussi des dizaines de   chaînes de paquet dans votre code Perl. Cette   est pas amusant. Et Perl devrait être amusant.

     

Maintenant, ça ne serait pas génial si vous pouviez   juste de lire dans la source de C que vous avez   déjà écrit et utiliser tous les types   il défini pour l'emballage et   déballage? C'est ce que   Convert :: Binary :: C fait.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top