2

我正在尝试将 3 个指针传递给 DLL 函数。我有:

{

$代码=1;
$len=100;
$str=" " x $len;

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

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

}

DLL 定义为void dllfunction(int* a, char* str, int* len);DLL 将修改三个指针所指向的所有变量。

但是,当我运行它时,我会出现段错误。Win32::API的文档指定我应该使用实际变量名而不是 Perl 变量引用。谁能告诉我我错过了什么?谢谢。

*更多信息:

printf()在DLL中添加了打印出三个指针的地址,并printf在Perl中打印出三个变量的引用。我得到以下信息

DLL:代码 = 0x10107458 错误 = 0x10046b50 str = 0x10107460

Perl:代码 = 0x101311b8 错误 = 0x101312a8 str = 0x10131230

知道为什么 DLL 得到错误的地址吗?

****更多信息

经过多次调试,我发现从 DLL 函数返回时会发生这种情况。我添加了 printf("done\n"); 作为这个 DLL 函数的最后一行,它确实输出,然后程序段错误。我猜它发生在 Win32::API 中?有没有人经历过这个?

此外,我可以从 DLL 访问所有三个变量的初始变量。所以指针是正确传递的,但由于某种原因,它在从 DLL 返回时会导致段错误。尝试将新数据复制到 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

好的,我按照亚当的链接到此页面。据此,调用应该是:

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

示例代码使用了一个带有 LPSTR(本质上是 char*)参数的函数,并且它使用了您所期望的变量,但这里有点:

对于指针,您必须使用变量名(没有 Perl 引用,只是一个普通的变量名)。

似乎表明我在这篇文章中列出的代码应该可以工作。

于 2008-12-09T21:09:31.810 回答
0

IANAPH,但我认为您需要使用参考,如下所示:

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

我最不确定的是 $str - 它可能不需要参考。段错误几乎肯定来自试图写入内存地址 1(或 100,取决于它首先尝试写入)的 DLL。

于 2008-12-09T20:31:53.010 回答
0

我不是 Windows 程序员,但看到:

对于指针,您必须使用变量名

对我来说意味着变量名,而不是变量本身。这行得通吗?

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

或者可能

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

顺便说一句,我不希望内存地址是相同的。Win32::API将需要将 Perl 数据元素转换为 Windows 可以理解的东西,我严重怀疑它们会占用相同的物理内存空间。

于 2008-12-09T22:08:26.997 回答