2

DLL 関数に 3 つのポインターを渡そうとしています。私は持っている:

{

$コード=1;
$len=100;
$str=" " x $len;

$function = new Win32::API(DLLNAME,'dllfunction','PPP','V');

$function->Call($code,$str,$len);

}

DLL は次のように定義されます。DLL はvoid dllfunction(int* a, char* str, int* len);、3 つのポインターが指すすべての変数を変更します。

ただし、これを実行するとセグメンテーション違反が発生します。Win32::APIのドキュメントでは、Perl 変数参照の代わりに実際の変数名を使用する必要があると指定されています。私が欠けているものを誰か教えてもらえますか?ありがとう。

*詳しくは:

printf()3 つのポインターのアドレスを出力するために DLLを追加しprintf、3 つの変数の参照を出力するために Perl を追加しました。そして、私は次のようになります

DLL : コード = 0x10107458 エラー = 0x10046b50 str = 0x10107460

Perl : コード = 0x101311b8 エラー = 0x101312a8 str = 0x10131230

DLL が間違ったアドレスを取得している理由がわかりましたか?

****詳しくは

多くのデバッグの後、DLL 関数から戻るときにこれが発生していることがわかりました。printf("done\n"); を追加しました。このDLL関数の最後の行として、これが出力され、プログラムがsegfaultします。Win32::API で起こっていると思いますか? 誰もこれを経験しましたか?

また、DLL から 3 つの変数すべての初期変数にアクセスできます。そのため、ポインタは正しく渡されますが、何らかの理由で DLL から戻るときに segfault が発生します。新しいデータを Perl 変数にコピーしようとするとセグメンテーション違反になるのでしょうか?

4

4 に答える 4

3

あっ!私はそれを考え出した。

問題はこれでした

  1. また、オプションで呼び出し規約を指定できます。これはデフォルトで '__stdcall' になりますが、代わりに '_cdecl' を指定することもできます。

dll 関数は extern "C" __declspec(dllexport) でエクスポートされたので、'_cdecl' フラグを使用する必要があるのではないかと考えました。

Win32::API('dll','dllfunction','PPP','V','_cdecl');

動作します!

みんな、ありがとう。

于 2008-12-09T22:30:27.717 に答える
0

OK、Adam のこのページへのリンクをたどりました。それによると、呼び出しは次のようになります。

$function->Call(code, $str, len)

サンプル コードでは、LPSTR (本質的には char*) パラメーターを持つ関数を使用しており、期待どおりに変数を使用していますが、このビットは次のとおりです。

ポインターには、変数名を使用する必要があります (Perl 参照ではなく、単純な変数名のみ)。

この投稿にリストしたコードが機能するはずであることを示しているようです。

于 2008-12-09T21:09:31.810 に答える
0

IANAPH ですが、次のように参照を使用する必要があると思います。

$function->Call(\$code, \$str, \$len)

私が最も確信していないのは $str です -参照は必要ないかもしれません。segfault はほぼ確実に、DLL がメモリ アドレス 1 (または最初に書き込みを試みるアドレスに応じて 100) に書き込もうとしていることが原因です。

于 2008-12-09T20:31:53.010 に答える
0

私はWindowsプログラマーではありませんが、見ています:

ポインターの場合、変数名を使用する必要があります

私にとっては、変数自体ではなく、変数名を意味します。これは機能しますか?

$function->Call('code', 'str', 'len');

または多分

$function->Call('$code', '$str', '$len');

ところで、メモリアドレスが同じであるとは思いません。Win32::APIPerl のデータ要素を Windows が理解できるものに変換する必要があり、それらが同じ物理メモリ スペースを占有することを真剣に疑っています。

于 2008-12-09T22:08:26.997 に答える