将 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 函数调用的主要内容,如果未能解决你的问题,请参考以下文章

如何将“this”指针传递给 C++ WinAPI 线程?

将指针分配给指针(并将指针传递给类)时使用删除的 C++ 混淆

如何将变量从变量传递给指针结构对象?

如何将组件指针从 QML 传递到 C++?

如何将结构从 C++ 应用程序传递到 C++ Win32 DLL?

QT怎样将一个结构体作为函数参数从C++传递到QML