[英]How do I "assign" the value in `CArray` that contains a memory address to a `Pointer`?
This is a NativeCall question.这是一个NativeCall问题。
I have 8 bytes (little endian) in a CArray
representing a memory address.我在代表 memory 地址的
CArray
中有 8 个字节(小端)。 How do I create a Pointer
out it?我如何创建一个
Pointer
出来呢?
( CArray
and Pointer
are two of NativeCall's C compatible types. Pointer
s are 8 bytes long. Things should line up, but how does one put the pointer address in a CArray
into a Pointer
in a way acceptable to NativeCall?) (
CArray
和Pointer
是 NativeCall 的 C 兼容类型中的两个Pointer
的长度为 8 个字节。事情应该是一致的,但是如何以 NativeCall 可接受的方式将CArray
中的指针地址放入Pointer
中?)
Here is an example of using the windows api call WTSEnumerateSessionsA() you mentioned in the comments:下面是使用 windows api 调用WTSEnumerateSessionsA()你在评论中提到的一个例子:
use NativeCall;
constant BYTE := uint8;
constant DWORD := uint32;
constant WTS_CURRENT_SERVER_HANDLE = 0; # Current (local) server
constant LPSTR := Str;
enum WTS_CONNECTSTATE_CLASS (
WTSActive => 0,
WTSConnected =>1,
WTSConnectQuery => 2,
WTSShadow => 3,
WTSDisconnected => 4,
WTSIdle => 5,
WTSListen => 6,
WTSReset => 7,
WTSDown => 8,
WTSInit => 9
);
constant WTS_CONNECTSTATE_CLASS_int := int32;
class WTS_SESSION_INFOA is repr('CStruct') {
has DWORD $.SessionId is rw;
has LPSTR $.pWinStationName is rw;
has WTS_CONNECTSTATE_CLASS_int $.State;
}
sub GetWTSEnumerateSession(
#`{
C++
BOOL WTSEnumerateSessionsA(
[in] HANDLE hServer,
[in] DWORD Reserved,
[in] DWORD Version,
[out] PWTS_SESSION_INFOA *ppSessionInfo,
[out] DWORD *pCount
);
Returns zero if this function fails.
}
DWORD $hServer, # [in] HANDLE
DWORD $Reserved, # [in] always 0
DWORD $Version, # [in] always 1
Pointer[Pointer] $ppSessionInf is rw, # [out] see _WTS_SESSION_INFOA and _WTS_CONNECTSTATE_CLASS;
DWORD $pCount is rw # [out] DWORD
)
is native("Wtsapi32.dll")
is symbol("WTSEnumerateSessionsA")
returns DWORD # If the function fails, the return value is zero.
{ * };
my $hServer = Pointer[void].new();
$hServer = WTS_CURRENT_SERVER_HANDLE; # let windows figure out what current handle is
my $ppSession = Pointer[Pointer].new(); # A pointer to another pointer to an array of WTS_SESSION_INFO
my DWORD $pCount;
my $ret-code = GetWTSEnumerateSession $hServer, 0, 1, $ppSession, $pCount;
say "Return code: " ~ $ret-code;
my $array = nativecast(Pointer[WTS_SESSION_INFOA], $ppSession.deref);
say "Number of session info structs: " ~ $pCount;
for 0..^ $pCount -> $i {
say "{$i} : Session id: " ~ $array[$i].SessionId;
say "{$i} : Station name: " ~ $array[$i].pWinStationName;
say "{$i} : Connection state: " ~ $array[$i].State;
}
Output (windows 11) Output(视窗 11)
Return code: 1
Number of session info structs: 2
0 : Session id: 0
0 : Station name: Services
0 : Connection state: 4
1 : Session id: 1
1 : Station name: Console
1 : Connection state: 0
How do I create a Pointer out it?
我如何创建一个指针出来呢?
I think you could use nativecast like this:我认为您可以像这样使用nativecast :
my $ptr = nativecast(CArray[Pointer], $array);
my Pointer $ptr2 = $ptr[$idx];
From the comments it seems like the native sub should return a pointer to an array of struct.从评论看来,本机 sub 应该返回一个指向结构数组的指针。 On linux I created the following example:
在 linux 上,我创建了以下示例:
test.c测试.c
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
typedef struct myStruct
{
int32_t A;
double B;
} mstruct;
void set_pointer(mstruct **arrayOfStruct)
{
mstruct *ptr = (mstruct *) malloc(sizeof(mstruct)*2);
printf("allocated memory at address: %p\n", ptr);
ptr[0].A = 10;
ptr[0].B = 1.1;
ptr[1].A = 20;
ptr[1].B = 2.1;
*arrayOfStruct = ptr;
}
p.raku : p.raku :
use v6;
use NativeCall;
class myStruct is repr('CStruct') {
has int32 $.A is rw;
has num64 $.B is rw;
}
sub set_pointer(Pointer[CArray[myStruct]] is rw) is native("./libtest.so") { * };
my $array-ptr = Pointer[CArray[myStruct]].new();
set_pointer($array-ptr);
my $array = nativecast(Pointer[myStruct], $array-ptr.deref);
say $array[0].A;
say $array[0].B;
say $array[1].A;
say $array[1].B;
Output : Output :
allocated memory at address: 0x5579f0d95ef0
10
1.1
20
2.1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.