将C ++结构指针从Perl传递给任意dll函数调用

时间:2009-12-06 17:58:49

标签: visual-studio perl dll pointers dllexport

我正在使用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调用的最佳方法。

提前致谢,
Naga Kiran

2 个答案:

答案 0 :(得分:2)

在模板中使用Z(NUL填充的字符串),如

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

另外,请查看Win32::API::Struct,它是Win32 :: API模块的一部分。

答案 1 :(得分:1)

对于任何复杂的事情,请查看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;
  

并没有真正增加   可读性。

     

现在想象你需要打包   数据完全不同   不同字节的架构   订购。你会看看包装   manpage再次,或许想出来   这样:

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

但是,如果你试图解包$ foo   再次,您的签名值已经转变   进入未签名的。

     

所有这些仍然可以通过管理   Perl的。但想象你的结构得到了   更复杂?想象一下你需要   支持不同的平台?想像   你需要改变   结构?你不仅需要   改变C源但也有几十个   在Perl代码中打包字符串。这个   没有乐趣。 Perl应该很有趣。

     

现在,如果可以,那不是很好   只需阅读你的C源代码   已编写并使用所有类型   在那里定义包装和   拆包?那是什么   转换:: Binary :: C可以。