2012-02-13 10 views
6

क्या एक अच्छा तरीका करने के लिए "डाली" एक एडीए String एक System.Adress को जो सीसी शून्य करने के लिए एडीए स्ट्रिंग परिवर्तित *

में void* को char* कास्टिंग

मैं जो एक सी पुस्तकालय इंटरफ़ेस हूँ के बराबर होगा है। ए सी प्रकार में एक संपत्ति है जो void* है, और लाइब्रेरी के उपयोगकर्ता आमतौर पर इस मान के रूप में सी-स्ट्रिंग द्वारा इंगित पते को असाइन करते हैं। उदा:

struct my_type { 
    void* value; 
}; 

int main() { 
    my_type t; 
    t.value = "banana"; 
} 

मैं एडीए में बराबर, एक एडीए स्ट्रिंग के साथ शुरू कैसे प्राप्त कर सकते हैं?

मैं इस समय इस तकनीक का उपयोग कर रहा हूं, लेकिन यह मेरे लिए फिश लगता है।

declare 
    str : constant String := "banana"; 
    data : constant char_array := To_C(str); 
    mine : my_type; 
begin 
    mine.value := data(data'First)'Address; 
end; 

मैं किसी भी समाधान, यहां तक ​​कि एडीए 2012

+2

आपको पैकेज 'Interfaces.C.Strings'' पर एक नज़र रखना चाहिए, जिसमें एक प्रकार 'chars_ptr' है। आपके द्वारा आयात किए गए सी फ़ंक्शन को शून्य * के बजाय chars_ptr प्रकार का उपयोग करना चाहिए। – oenone

+2

इसके अलावा, यहां दिए गए सुझाए गए समाधान देखें: http://en.wikibooks.org/wiki/Ada_Programming/Types/access#Where_is_void.2A.3F – oenone

+0

प्रकार का 'शून्य *' सदस्य 'शून्य * 'है क्योंकि यह कुछ भी पता करने में सक्षम होना चाहिए; सिर्फ एक स्ट्रिंग नहीं।यही कारण है कि 'g ++' ने इसके लिए एडीए स्पेक उत्पन्न किया और 'System.Address' का उपयोग किया। मुझे फिलहाल तकनीक मिल रही है फिलहाल काम कर रहा है। शायद यह आवाज है? – Anthony

उत्तर

2

आप एक टिप्पणी है कि आप void* उपयोग कर रहे हैं ", क्योंकि यह कुछ भी पता लेने के लिए सक्षम होना चाहिए में उल्लेख के साथ ठीक हूँ, न सिर्फ एक स्ट्रिंग। "

तो फिर, किसी को यह पूछना है कि सामान्य-सूचक सामान्य रूप से टाइपिंग और उप-टाइपिंग सुविधाओं का लाभ उठाने के लिए एडा में कैसे अनुवाद करता है। मैं प्रस्तुत करता हूं कि इस संदर्भ में "कुछ भी" सामान्य रूप से हल नहीं किया जा सकता है; यह कहना है कि, यदि आप निर्माण की 'लचीलापन' को बनाए रखना चाहते हैं तो आपको अपने टाइप-सिस्टम के साथ प्रदान किए गए फायदे बलिदान करना होगा। इसके अलावा, मैं प्रस्तुत करता हूं कि प्रस्तुत किया गया है, आमतौर पर "कुछ भी" के लिए विश्वसनीय रूप से उपयोग करना असंभव है।

मैं यह कहता हूं क्योंकि निहित "कुछ भी" की लंबाई निर्धारित करने की कोई विधि नहीं है। यदि यह एक स्ट्रिंग है तो लंबाई बिंदु-पते से होती है, जो पहले एनयूएल चरित्र (ASCII 0) तक लगातार गिनती होती है। । हालांकि, लंबाई निर्धारित करने के लिए कोई विधि नहीं है यदि यह एक स्ट्रिंग नहीं है (हम सरणी [1,2,3] या ओबीजेईसीटी की लंबाई/आकार कैसे जानेंगे ... और इसलिए हमारे पास निर्धारित करने के लिए कोई विधि नहीं है "कुछ भी" की लंबाई।

स्थिर निर्धारित/स्थिर कोड लिखने में लंबाई निर्धारित करना एक महत्वपूर्ण कारक है, क्योंकि यदि आप बफर ओवरफ़्लो को आमंत्रित नहीं कर रहे हैं।


लेकिन,, कि है छोड़ना यदि आप डेटा के बारे में कुछ जानकारी उपलब्ध कराने के पैरामीटर के माध्यम से या my_struct बदल रहा है कि क्या है, तो हम उस जानकारी का उपयोग कर सकते हैं एक बेहतर प्रकार-रूपांतरण के निर्माण के लिए कर सकते हैं। (आम तौर पर, आपके पास एक प्रकार के बारे में अधिक जानकारी बेहतर होती है, क्योंकि आप उन तरीकों से वैधता के डेटा की जांच कर सकते हैं, जिनके बारे में आप पहले नहीं कर सकते थे; या बेहतर अभी तक, आपके लिए कंपाइलर जांचें।)

Type Data_Type is Array(Positive Range <>) of Interfaces.Unsigned_8; 
    For Data_Type'Component_Size Use 8; 


Function Some_Data(Stream : not null access Ada.Streams.Root_Stream_Type'Class; 
        Length : In Positive) Return Data_Type is 
    begin 
    Return Result : Data_Type(1..Length) do 
     For Index in Result'Range loop 
      Interfaces.Unsigned_8'Read(Stream, Result(Index)); 
     end Loop; 
    End Return; 
    end Some_Data; 

आप उपरोक्त का उपयोग 8-बिट हस्ताक्षरित पूर्णांक की सरणी उत्पन्न करने के लिए कर सकते हैं जिसमें स्ट्रीम से डेटा होगा। यह सामान्य बातों में आपको क्या करना होगा, हालांकि आप सी-आयात के साथ काम कर रहे हैं, क्योंकि आप इसे कुछ संशोधित कर सकते हैं ताकि ए) Temp वैरिएबल है जो Result जैसे सरणी है For Temp'Address Use [...] इसे my_type.value पर ओवरले करने के लिए और उसके बाद इसे कॉपी करने के लिए फॉर-लूप का उपयोग करें।