通过 C++从 Perl 到任意 dll 函数调用的结构指针

发布于 2024-08-14 06:51:46 字数 637 浏览 7 评论 0原文

我正在使用 Win32::API 调用在 DLL 中导出的任意函数,该函数接受 C++ 结构指针。

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 调用的最佳方法吗?

预先感谢,
纳迦基兰

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,$vendor,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 Kiran

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沉默的熊 2024-08-21 06:51:46

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

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

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

Use 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.

若水微香 2024-08-21 06:51:46

对于任何复杂的事情,请查看 Convert::Binary::C。乍一看可能令人望而生畏,但一旦您意识到它的力量,就会大开眼界。

更新:让我添加一些信息。您需要查看 模块手册页的特定部分了解使用它的主要原因。为了方便起见,我将引用它:

为什么使用 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 可以。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文