我正在尝试将3个指针传递给DLL函数。我有:
{ $code=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变量引用。谁能告诉我我失踪了什么?感谢。
*更多信息:
我在DLL中添加printf()
以打印出三个指针的地址,并在Perl中添加printf
以打印出三个变量的引用。我得到以下
DLL:代码= 0x10107458错误= 0x10046b50 str = 0x10107460
Perl:代码= 0x101311b8错误= 0x101312a8 str = 0x10131230
知道为什么DLL会收到错误的地址吗?
****更多信息
经过大量调试后,我发现从DLL函数返回时会发生这种情况。我添加了printf(“done \ n”);作为这个DLL函数的最后一行,这确实输出,然后程序段错误。我猜它在Win32 :: API中发生了吗?有没有人经历过这个?
此外,我能够从DLL访问所有三个变量的初始变量。因此指针正确传递,但由于某种原因,它从DLL返回时会导致段错误。尝试将新数据复制到Perl变量时,可能是segfaulting?
答案 0 :(得分:3)
AH !!我想通了。
问题是这个
- 您可以选择指定调用约定,默认为'__stdcall',或者您也可以指定'_cdecl'。
醇>
dll函数是用extern“C”__declspec(dllexport)导出的,所以我想也许我应该使用'_cdecl'标志。
的Win32 API ::( 'DLL', 'dllfunction', 'PPP', 'V', '_ CDECL');
作品!
谢谢大家。
答案 1 :(得分:0)
IANAPH,但我认为您需要使用reference,如下所示:
$function->Call(\$code, \$str, \$len)
我最不确定的是$ str - 可能不需要参考。段错误几乎肯定来自DLL试图写入内存地址1(或100,取决于它首先尝试写入)。
答案 2 :(得分:0)
好的,我跟着Adam的this page链接。据此,电话应该是:
$function->Call(code, $str, len)
示例代码使用带有LPSTR(本质上是char *)参数的函数,它使用您期望的变量,但这一点在这里:
对于指针,您必须使用变量名称(没有Perl引用,只是一个普通的变量名称)。
似乎表明我在这篇文章中列出的代码应该工作。
答案 3 :(得分:0)
我不是Windows程序员,但看到了:
对于指针,您必须使用变量名
对我来说意味着变量名,而不是变量本身。这有用吗?
$function->Call('code', 'str', 'len');
或者
$function->Call('$code', '$str', '$len');
是的,我不希望内存地址相同。 Win32::API
需要将Perl数据元素转换为Windows可以理解的内容,并且我非常怀疑它们会占用相同的物理内存空间。