2016-02-06 6 views
6

शामिल मैं निम्नलिखित Struct हैNativeCall Struct जो सूचक

typedef struct _info{ 
    DWORD myInfo; 
    BYTE *pInfo; 
    LPWSTR ExtData; 

} Info; 

मैं इस struct का प्रतिनिधित्व किया NativeCall इस प्रकार का उपयोग कर:

class Info is repr('CStruct') { 
    has int32 $.myInfo; 
    has Pointer[int8] $.pInfo ; 
    has Pointer[int16] $.ExtData; 
} 

है इस प्रतिनिधित्व ठीक? मैं $.pInfo द्वारा इंगित डेटा को कैसे एक्सेस और सेट कर सकता हूं?

उत्तर

3

प्रतिनिधित्व मेरे लिए ठीक लगता है ... यह देखते हुए इस आविष्कार सी पुस्तकालय: (मेरी सी foo पर लेने नहीं करते कृपया - अपनी बात के बगल में)

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

typedef unsigned long int DWORD; 
typedef unsigned char BYTE; 
typedef char * LPWSTR; 

typedef struct _info{ 
    DWORD myInfo; 
    BYTE *pInfo; 
    LPWSTR ExtData; 
} Info; 


Info* create_info(); 
void display_info(); 
void double_info(Info*); 

Info* 
create_info() { 
    DWORD init_myinfo = 2016; 
    BYTE init_pinfo  = 37; 
    char init_ExtData[] = "Hello World"; 

    Info *new_info = malloc(sizeof(Info)); 
    if (new_info == NULL) { 
     printf("Memory alloc failed\n"); 
     exit(1); 
    } 

    new_info->myInfo = init_myinfo; 

    BYTE *pinfo = malloc(sizeof(BYTE)); 
    *pinfo = init_pinfo; 
    new_info->pInfo = pinfo; 

    char *ext_data = malloc(sizeof(init_ExtData)); 
    strcpy(ext_data, init_ExtData); 
    new_info->ExtData = ext_data; 

    return new_info; 
} 

void 
display_info(Info *inf) { 
    printf("myInfo: %lu\n", inf->myInfo); 
    printf("pInfo: %i\n", *inf->pInfo); 
    printf("ExtData: %s\n", inf->ExtData); 
} 

void 
double_info(Info *inf) { 

    inf->myInfo *= 2; 

    if (*(inf->pInfo) < 128) 
     *(inf->pInfo) *= 2; 

    int extdata_len = strlen(inf->ExtData); 
    char *tmp_extdata = malloc(extdata_len * 2 + 2); 
    strncpy(tmp_extdata, inf->ExtData, extdata_len); 
    tmp_extdata[extdata_len] = '+'; 
    strcpy(&tmp_extdata[extdata_len+1], inf->ExtData); 
    inf->ExtData = tmp_extdata; 
} 

फिर अपने perl6 struct परिभाषा NativeCall का उपयोग कर अधिक या कम काम:

#!/usr/bin/env perl6 
use NativeCall; 

class Info is repr('CStruct') { 
    has int32   $.myInfo; 
    has Pointer[int8] $.pInfo ; 
    has Pointer[Str] $.ExtData; 

    method Str { 
     qq:to/END HERE/; 
     myInfo: $!myInfo 
     pInfo: { $!pInfo.deref } 
     ExtData: { $!ExtData.deref } 
     END HERE 
    } 
} 

our sub create_info() returns Info is native('pinfo') { * } 
our sub display_info(Info) is native('pinfo') { * } 
our sub double_info(Info is rw) is native('pinfo') { * } 

my Info $inf = create_info(); 
say 'Displaying $inf after calling create_info()'; 
display_info $inf; 

double_info $inf; 
say 'Displaying $inf after calling double_info()'; 
display_info $inf; 

say 'Displaying $inf by calling attribute methods on Perl6 object'; 
say "myInfo: $inf.myInfo()"; 
say "pInfo: $inf.pInfo.deref()"; 
say "ExtData: $inf.ExtData.deref()"; 

say 'Displaying $inf by stringifying Perl6 object'; 
say "$inf"; 
exit 0; 

इसका उत्पादन एक रन;

Displaying $inf after calling create_info() 
myInfo: 2016 
pInfo: 37 
ExtData: Hello World 
Displaying $inf after calling double_info() 
myInfo: 4032 
pInfo: 74 
ExtData: Hello World+Hello World 
Displaying $inf by calling attribute methods on Perl6 object 
myInfo: 4032 
pInfo: 74 
ExtData: Hello World+Hello World 
Displaying $inf by stringifying Perl6 object 
myInfo: 4032 
pInfo: 74 
ExtData: Hello World+Hello World 

वैकल्पिक रूप से, कोई perl6 कक्षा के अंदर 'गोंद' को छुपा सकता है;

#!/usr/bin/env perl6 
use NativeCall; 

class Info is repr('CStruct') { 
    has int32   $.myInfo is rw ; 
    has Pointer[int8] $!pInfo ; 
    has Pointer[Str] $!ExtData ; 

    my sub create_info() returns Info is native('pinfo') { * } 
    my sub display_info(Info)   is native('pinfo') { * } 
    my sub double_info(Info is rw) is native('pinfo') { * } 

    method new  { create_info()  } 
    method display { display_info(self) } 
    method double { double_info(self) } 

    method pInfo { $!pInfo.deref  } 
    method ExtData { $!ExtData.deref } 

    method Str { 
     qq:to/END HERE/; 
     myInfo: { self.myInfo } 
     pInfo: { self.pInfo } 
     ExtData: { self.ExtData } 
     END HERE 
    } 
} 

my Info $inf .= new; 
say 'Displaying $inf after calling .new'; 
$inf.display ; 

$inf.double ; 
say 'Displaying $inf after calling .double'; 
$inf.display ; 

say 'Displaying $inf by calling attribute methods on Perl6 object'; 
say "myInfo: $inf.myInfo()"; 
say "pInfo: $inf.pInfo()"; 
say "ExtData: $inf.ExtData()"; 

$inf.myInfo = 12046 ; 
say 'Displaying $inf by stringifying Perl6 object'; 
say "$inf"; 
exit 0; 

... एक बहुत साफ दिखने वाला। यह इसी तरह पैदा करता है;

Displaying $inf after calling .new 
myInfo: 2016 
pInfo: 37 
ExtData: Hello World 
Displaying $inf after calling .double 
myInfo: 4032 
pInfo: 74 
ExtData: Hello World+Hello World 
Displaying $inf by calling attribute methods on Perl6 object 
myInfo: 4032 
pInfo: 74 
ExtData: Hello World+Hello World 
Displaying $inf by stringifying Perl6 object 
myInfo: 12046 
pInfo: 74 
ExtData: Hello World+Hello World 

नोट्स:

(1) आप प्रकार सूचक की विशेषताओं पर .deref() विधि फोन वास्तविक डेटा की ओर इशारा किया जा रहा प्राप्त करने के लिए। मैं हो रही है "कर सकते हैं '-

(2) NativeCall documentation एक बार से अधिक पढ़ा ;-)

(3) कोई फर्क नहीं पड़ता कि मैं क्या करने की कोशिश की, मैं को संशोधित नहीं कर सकता डेटा संकेत के माध्यम से संदर्भित किया जा रहा हो गया है अपरिवर्तनीय डेटा संशोधित नहीं करें "।

(4) वाईएमएमवी

संबंधित मुद्दे