将 C++ 结构指针从 Perl 传递给任意 dll 函数调用
Posted
技术标签:
【中文标题】将 C++ 结构指针从 Perl 传递给任意 dll 函数调用【英文标题】:Passing C++ structure pointer from Perl to arbitary dll function call 【发布时间】:2009-12-06 17:58:49 【问题描述】:我正在使用 Win32::API 调用在接受 C++ 结构指针的 DLL 中导出的任意函数。
struct PluginInfo
int nStructSize;
int nType;
int nVersion;
int nIDCode;
char szName[ 64 ];
char szVendor[ 64 ];
int nCertificate;
int nMinAmiVersion;
;
由于我们需要使用“pack”函数来构造结构,并且需要传递一个参数
my $name = " " x 64;
my $vendor = " " x 64;
my $pluginInfo = pack('IIIIC64C64II',0,0,0,0,$name,$vendor,0,0);
它没有正确构建结构。 似乎应用于 C 的长度参数会吞噬这些参数。 有人可以建议从 Perl 和传递到 dll 调用中构建这种结构的最佳方法。
提前致谢, 娜迦基兰
【问题讨论】:
【参考方案1】:在您的模板中使用Z
(NUL 填充字符串),如
my $pluginInfo = pack('IIIIZ64Z64II',0,0,0,0,$name,$vendor,0,0);
另外,看看Win32::API::Struct
,它是 Win32::API 模块的一部分。
【讨论】:
szName/szVendor 中的 z 向我暗示它应该是 Z64,而不是 A64;这会将最多 63 个字节的 $name/$vendor 放入 $pluginInfo,nul 填充到 64 个字节。【参考方案2】:对于任何复杂的事情,请查看Convert::Binary::C。一开始可能会让人望而生畏,但一旦你意识到它的力量,就会大开眼界。
更新:让我补充一点信息。您需要查看specific section of the module's manpage 是使用它的主要原因。为方便起见,我将引用它:
为什么要使用 Convert::Binary::C?
假设您要打包(或解包)数据 根据以下C 结构:
struct foo
char ary[3];
unsigned short baz;
int bar;
;
你当然可以使用 Perl 的包 和解包函数:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
但这意味着结构 成员是字节对齐的。如果他们是 长对齐(这是默认的 大多数编译器),你必须写
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
这并没有真正增加 可读性。
现在假设您需要打包 完全不同的数据 不同字节的架构 命令。你会查看包裹 再次联机手册,也许想出 这个:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
但是,如果您尝试解压缩 $foo 再次,您的签名值已经转变 变成未签名的。
这一切仍然可以通过 珀尔。但是想象一下你的结构得到 更复杂?想象一下你需要 支持不同的平台?想象 您需要对 结构?你不仅需要 换C源还要几十 在 Perl 代码中打包字符串。这 不好玩。 Perl 应该很有趣。
现在,如果可以的话,那不是很好吗 只需阅读您已阅读的 C 源代码 已经编写并使用所有类型 在那里定义用于包装和 开箱?就是这样 Convert::Binary::C 可以。
【讨论】:
以上是关于将 C++ 结构指针从 Perl 传递给任意 dll 函数调用的主要内容,如果未能解决你的问题,请参考以下文章
将指针分配给指针(并将指针传递给类)时使用删除的 C++ 混淆