2009-05-18 20 views
5

C++ में ऐसा किया है करने के लिए एक बाइट [] आवंटित करने के लिए कैसे:एक रिकार्ड

tPacket * packet = (tPacket *)data; //data is byte[] array; tPacket is a structure 

सी # में:

tPacket t = new tPacket(); 
GCHandle pin = GCHandle.Alloc(data, GCHandleType.Pinned); 
t = (tPacket)Marshal.PtrToStructure(pin.AddrOfPinnedObject(), typeof(tPacket)); 
pin.free(); 

डाटा पैकेट के बाद एक बफर प्राप्त के रूप में इस्तेमाल एक बाइट सरणी है टीसीपी पर प्राप्त होता है। वह कोड डेटा को टीपीएकेट (एक संरचना) के उदाहरण में रखता है ताकि मैं बाद में संरचना तक पहुंच सकूं।

डेल्फी में यह कैसे किया जाता है?

+0

मुझे आशा है कि आपका सी ++ टीपीएकेट एक पीओडी (कोई आभासी तरीकों) नहीं है और इसमें कोई पॉइंटर्स या रीफ्रेंस नहीं है। और मुझे आशा है कि आपका सी # टीपैकेट एक वैल्यू प्रकार है जिसमें केवल मूल्य प्रकार होते हैं (जिसमें केवल मूल्य प्रकार होते हैं, ... इसलिए आपके ऑब्जेक्ट ग्राफ़ में कोई संदर्भ प्रकार नहीं है)। – mmmmmmmm

उत्तर

4

आप कर सकते हैं भी दोनों संरचनाओं के लिए मजबूर करने निरपेक्ष कीवर्ड का उपयोग एक ही स्मृति का पता साझा करने के लिए: एस मैं के लिए लिखा

var 
    Data: array[1..SizeOf(TMyStruct)] of byte; 
    s : TMyStruct absolute Data; 

कोई डेटा एक चाल या सूचक कास्टिंग किए बिना डेटा के रूप में भी उपलब्ध है।

+0

बेशक, यह गतिशील सरणी के बाद से काम नहीं करेगा संदर्भ प्रकार हैं। सरणी को गतिशील होना चाहिए। –

+0

मैं डेटा को गतिशील सरणी के रूप में घोषित नहीं करता हूं। जब रिकॉव() को कॉल करते हैं - डेटा का आकार 8192 बाइट होता है। :) धन्यवाद यह काम किया। –

+0

अच्छा, यह अच्छा है कि यह आपके लिए काम करता है, लेकिन क्या उत्तर कृपया कुछ उपयोग करने योग्य हो सकता है? साथ ही, पूर्ण चाल इस तरह के साधारण मामलों के लिए अच्छा हो सकती है, लेकिन बिना किसी स्थान या टाइपकास्ट के डेटा के रूप में एस को उपलब्ध करने का बेवकूफ तरीका सी यूनियन के समान एक संस्करण रिकॉर्ड का उपयोग करना होगा। – mghie

2

यह मुश्किल हो सकता है क्योंकि आपको यह सुनिश्चित करना है कि आपका स्रोत और गंतव्य संरचना लेआउट समान हैं। वे कर रहे हैं, तो आप 2 विकल्प हैं, या तो डाटा सरणी के लिए एक सूचक का उपयोग करें, या एक मेमोरी प्रतिलिपि का उपयोग करें:

सूचक:

type 
    // Declare a pointer type for your struct. 
    PMyStruct = TMyStruct^; 

... 

var 
    ptr: PMyStruct; 
begin 
    ptr := PMyStruct(Cardinal(@Data)); 
    // use ptr... 
end; 

मेमोरी प्रतिलिपि:

var 
    Data: array of Byte; 
    s: TMyStruct; 
begin 
    // fill Data... 
    if SizeOf(s) <> Length(Data) then 
    raise Exception.Create('Input size is not the same size as destination structure.'); 
    CopyMemory(@s, @Data, Length(Data)); 
    // use s... 
end; 
+0

समस्या यह है कि सी ++/सी # कोड में यह समान नहीं है। संरचना के आकार 10 बाइट हैं और पैकेट आकार 2000 बाइट्स से अधिक हो सकता है। –

+0

बस पहले उदाहरण का उपयोग करें, सूचक विधि। यह सी ++ कोड के समान है। –

+0

व्यक्तिगत रूप से, मैं @ डेटा [0] पर लिखूंगा, क्योंकि शायद आप सूचक मूल्य को ओवरराइट नहीं करना चाहते हैं। –

3

आप डेल्फी में कर सकते हैं कि आप सी ++ में क्या करेंगे। रिकॉर्ड पॉइंटर के लिए नामित प्रकार को परिभाषित करें, हालांकि, डेल्फी आपको बयानों में प्रकार परिभाषित करने नहीं देता है।

type 
    PPacket = ^TPacket; 
var 
    packet: PPacket; 

packet := PPacket(@data[0]); 
  • कारण मैं @data[0] का उपयोग किया है कि यह है कि क्या डेटा एक गतिशील सरणी है की परवाह किए बिना काम करता है। यदि यह एक गतिशील सरणी है, तो data वास्तव में पैकेट की पहली बाइट के लिए सूचक है, तो यह काम करेगा:

    packet := PPacket(data); // for dynamic array only 
    

    लेकिन अगर data है नहीं एक गतिशील सरणी, तो उस प्रकार कलाकारों जीता ' टी मान्य नहीं है। data को आप के बजाय पूरे करने होंगे टाइप-कास्ट एक सूचक, इस तरह:

    packet := PPacket(@data); // for static array only 
    

    कि अगर यह एक गतिशील सरणी है काम नहीं करेगा। पहला कोड दोनों मामलों में काम करेगा। लेकिन अगर आपके पास रेंज जांच सक्षम है (और आपको शायद चाहिए), तो मुझे लगता है कि पहला कोड अपवाद उठाएगा यदि data शून्य-लंबाई गतिशील सरणी है, तो सावधान रहें।


आप के बजाय सी # मार्ग से जाने के लिए है, जहां आप एक अलग TPacket चर में सरणी से बाइट्स कॉपी चाहते हैं, तो मैं इस का उपयोग करेंगे:

var 
    packet: TPacket; 

// Source param comes first. Params are passed by 
// reference automatically. 
Move(data[0], packet, SizeOf(packet)); 

आप ' आपको यह सुनिश्चित करने की आवश्यकता होगी कि data में पूरे TPacket मान को भरने के लिए पर्याप्त बाइट शामिल हैं।TPacket में कोई संकलक-प्रबंधित प्रकार नहीं था, जैसे string, Variant, IUnknown, या गतिशील-सरणी प्रकार। जब भी मामला नहीं है तो पॉइंटर टाइप-कास्टिंग और न ही Move अच्छी तरह से व्यवहार करें।

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