Raku/Perl6:如何使用NativeCall编写空值(NULL)?

5

https://docs.perl6.org/language/nativecall

 "As you may have predicted by now, a NULL pointer
 is represented by the type object of the struct type."

https://learn.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regqueryvalueexw

 C++
 LSTATUS RegQueryValueExW(
   HKEY    hKey,
   LPCWSTR lpValueName,
   LPDWORD lpReserved,
   LPDWORD lpType,
   LPBYTE  lpData,
   LPDWORD lpcbData
 );

 lpReserved
 This parameter is reserved and must be NULL.

使用“native”技术,我该如何满足“NULL”要求?
constant WCHAR   := uint16;
constant DWORD   := int32;

sub RegQueryValueExW( DWORD, WCHARS, DWORD, DWORD, DWORD is rw, DWORD is rw ) is native("Kernel32.dll") returns DWORD { * };

$RtnCode = RegQueryValueExW( $Handle, $lpValueName, int32, REG_DWORD, $lpData, $lpcbData );

"int32" 的返回值:

Cannot unbox a type object (int32) to int in method
CALL-ME at C:\rakudo\share\perl6\sources \947BDAB9F96E0E5FCCB383124F9
23A6BF6F8D76B (NativeCall) line 587
非常感谢,-T

1
你能否尝试传递一个显式的0而不是类型int32 - Håkon Hægland
传递一个零不起作用。 - Todd
好的,我想我明白了:lpReserved 是一个 DWORD * 而不仅仅是一个 DWORD - Håkon Hægland
我投票关闭这个问题,因为它最多只是一个打字错误,最坏的情况是一个未指明的“小错误”。第一条评论(“你能试着传递一个明确的0吗?”)找到了解决方案,但是托德在发布并接受自己的答案之前回复说“传递零不起作用”,而他的答案却说“只需传递零。我犯了个小错误”。在我看来,应该有一个即时信号表明阅读这个问题很可能会浪费读者的时间。 - undefined
2个回答

5

要传递一个指向 DWORD 的指针,您可以使用 CArray[DWORD]。例如,在这里,我创建了一个测试库 libmylib.so,其中包含一个名为 foo() 的函数,该函数接受 DWORD *(又称 int32_t *)参数:

#include <stdio.h>
#include <stdint.h>

void foo (int32_t *bar) {
    if ( bar == NULL ) {
        printf( "Got NULL pointer\n" ); 
    }
    else {
        printf("Got bar: %d\n", bar[0]);
    }
}

然后使用以下方式测试与此库的Raku接口:

use v6;
use NativeCall;

constant DWORD := int32;
sub foo(CArray[DWORD]) is native("./libmylib.so") { * };
my @bar := CArray[DWORD].new;
@bar[0]  = 1;
foo(@bar);
foo(CArray[DWORD]);  # <-- Use a type object to pass a NULL pointer

输出:

Got bar: 1
Got NULL pointer

0

JJ和Brad在Perl6邮件列表上是正确的。对于NULL,只需传递一个零即可。我在其他地方犯了一个错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接