2

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呼び出しへの受け渡しからこの構造を構築するための最良の方法を提案できますか?

よろしくお願いします、
ナガキラン

4

2 に答える 2

2

Zテンプレートでは、次のように(NULが埋め込まれた文字列)を使用します

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

また、Win32::API::StructWin32::APIモジュールの一部であるを見てください。

于 2009-12-06T19:22:20.707 に答える
1

複雑なことについては、Convert::Binary::Cを調べてください。最初は気が遠くなるかもしれませんが、その威力を実感すると、目を見張るものがあります。

更新: 少し情報を追加させてください。モジュールを使用する主な理由については、モジュールのマンページの特定のセクションを確認する必要があります。便宜上引用します:

Convert::Binary::C を使用する理由

次の C 構造に従ってデータをパック (またはアンパック) したいとします。

struct foo {
  char ary[3];
  unsigned short baz;
  int bar;
};

もちろん、Perl の pack および unpack 関数を使用することもできます。

@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 を再度解凍しようとすると、符号付きの値が符号なしの値に変わります。

これらはすべて Perl で管理できます。しかし、構造がより複雑になると想像してみてください。さまざまなプラットフォームをサポートする必要があると想像してみてください。構造を変更する必要があると想像してみてください。C ソースを変更するだけでなく、Perl コード内の多数のパック文字列も変更する必要があります。これは面白くありません。そしてPerlは楽しいはずです。

さて、すでに書いた C ソースを読み込んで、そこで定義されているすべての型を使用して、パックとアンパックを行うことができたら素晴らしいと思いませんか? それが Convert::Binary::C の機能です。

于 2009-12-07T08:41:49.287 に答える