Passing C++ structure pointer from Perl to arbitary dll function call
I am using Win32::API to call an arbitary function exported in a DLL which accepts a C++ structure pointer.
struct PluginInfo {
int nStructSize;
int nType;
int nVersion;
int nIDCode;
char szName[ 64 ];
char szVendor[ 64 ];
int nCertificate;
int nMinAmiVersion;
};
As we need to use the "pack" function to construct the structure and need to pass an argument
my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendo开发者_如何学Pythonr,0,0);
Its not constructing the structure properly.
It seems that length argument applied to C will gobble those many arguments. Can some one please suggest the best way to construct this structure form Perl and passon to dll call.Thanks in advance,
Naga KiranUse Z
(NUL-padded string) in your template, as in
my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);
Also, take a look at Win32::API::Struct
, which is part of the Win32::API module.
For anything complicated, check out Convert::Binary::C. It may seem daunting at first, but once you realize its power, it's an eye opener.
Update: Let me add a bit of information. You need to have a look at a specific section of the module's manpage for the prime reason to use it. I'll quote it for convenience:
Why use Convert::Binary::C?
Say you want to pack (or unpack) data according to the following C structure:
struct foo {
char ary[3];
unsigned short baz;
int bar;
};
You could of course use Perl's pack and unpack functions:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
But this implies that the struct members are byte aligned. If they were long aligned (which is the default for most compilers), you'd have to write
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
which doesn't really increase readability.
Now imagine that you need to pack the data for a completely different architecture with different byte order. You would look into the pack manpage again and perhaps come up with this:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
However, if you try to unpack $foo again, your signed values have turned into unsigned ones.
All this can still be managed with Perl. But imagine your structures get more complex? Imagine you need to support different platforms? Imagine you need to make changes to the structures? You'll not only have to change the C source but also dozens of pack strings in your Perl code. This is no fun. And Perl should be fun.
Now, wouldn't it be great if you could just read in the C source you've already written and use all the types defined there for packing and unpacking? That's what Convert::Binary::C does.
精彩评论