Raku/Perl6:如何使用 NativeCall 编写 NULL
Raku/Perl6: how do you code a NULL with NativeCall
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://docs.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" returns:
Cannot unbox a type object (int32) to int in method
CALL-ME at C:\rakudo\share\perl6\sources 7BDAB9F96E0E5FCCB383124F9
23A6BF6F8D76B (NativeCall) line 587
非常感谢,
-T
要将指针传递给 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
Perl6 邮件列表中的 JJ 和 Brad 是正确的。对于 NULL,只需传递一个零即可。我在其他地方有一个嘘声。
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://docs.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" returns:
Cannot unbox a type object (int32) to int in method CALL-ME at C:\rakudo\share\perl6\sources 7BDAB9F96E0E5FCCB383124F9 23A6BF6F8D76B (NativeCall) line 587
非常感谢, -T
要将指针传递给 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
Perl6 邮件列表中的 JJ 和 Brad 是正确的。对于 NULL,只需传递一个零即可。我在其他地方有一个嘘声。