2009-09-21 14 views
5

मैं कुछ सी # इंटरऑप काम कर रहा हूँ।सी #: एक संरचना को marshalling जिसमें arrays

#pragma pack(push,1) 
typedef struct 
{ 
    unsigned __int64 Handle; 
    LinkType_t Type; 
    LinkState_t State; 
    unsigned __int64 Settings; 
    signed __int8 Name[MAX_LINK_NAME]; 
    unsigned __int8 DeviceInfo[MAX_LINK_DEVINFO]; 
    unsigned __int8 Reserved[40]; 
} LinkInfo_t; 

यह बात एक सी # struct में तब्दील करने के लिए अपने प्रयास है: मैं निम्नलिखित struct है

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
public struct LinkInfo_t 
{ 
    [MarshalAs(UnmanagedType.U8)] 
    public UInt64 Handle; 
    MarshalAs(UnmanagedType.I4)] 
    public LinkType_t Type; 
    [MarshalAs(UnmanagedType.I4)] 
    public LinkState_t State; 
    [MarshalAs(UnmanagedType.U8)] 
    public UInt64 Settings; 
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_LINK_NAME)] 
    public string Name; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_LINK_DEVINFO, ArraySubType = UnmanagedType.U1)] 
    public byte[] DeviceInfo; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40, ArraySubType = UnmanagedType.U1)] 
    public byte[] Reserved; 
} 

बहरहाल, जब भी मैं struct नाम, DeviceInfo, प्रारंभ और सुरक्षित क्षेत्रों पूरी तरह से तैयार कर रहे हैं शून्य करने के लिए। मैं यह कैसे तय करुं?

उत्तर

7

सरणियों के लिए, fixed संशोधक का उपयोग करने का प्रयास करें: जब भी मैं struct नाम, DeviceInfo प्रारंभ

public fixed byte DeviceInfo[MAX_LINK_DEVINFO]; 
    public fixed byte Reserved[40]; 
+0

यह सरणी के लिए काम करता है। हालांकि सही वाक्यविन्यास सार्वजनिक फिक्स्ड बाइट डिवाइसइन्फो [MAX_LINK_DEVINFO] है; मुझे भी संरचना को असुरक्षित घोषित करना होगा। –

+0

आप सही हैं, मैंने इसे असुरक्षित और निश्चित के बजाय –

3

, और सुरक्षित क्षेत्रों सब शून्य पर सेट कर रहे हैं

यह सही है, और आपकी परिभाषा मेरे लिए ठीक दिखती है (बीटीडब्ल्यू, आपको आदिम फ़ील्ड पर [MarshalAs] की आवश्यकता नहीं है, डिफ़ॉल्ट व्यवहार वह है जो आपने वहां निर्दिष्ट किया है)। चूंकि आपके सरणी फ़ील्ड null हैं, इसलिए मार्शलर उनके बारे में कुछ भी नहीं करेगा जब आपकी संरचना को अप्रबंधित स्मृति में मार्शल कर दिया जाए, लेकिन यह अनचाहे होने पर तार और सरणी बनाने जा रहा है।

+1

तय किया है, कोड का उपयोग करने से पहले बाइट सरणी आवंटित करनी चाहिए। मैं आम तौर पर पी/invoke के लिए structs पर एक कन्स्ट्रक्टर है जहां किसी भी सरणी स्वचालित रूप से आवंटित कर रहे हैं। – erict

0

एंटोन Tykhyy क्या कहता है सही है। मैं बस कुछ उदाहरणों के साथ स्पष्टीकरण देना चाहता हूं। 'निश्चित' कार्यों का उपयोग करना, लेकिन यह आपको 'असुरक्षित' का उपयोग करने के लिए भी मजबूर करता है। मैं जहां भी संभव हो असुरक्षित उपयोग से बचने के लिए पसंद है। मार्शल का उपयोग करना उस के आसपास जाने का एक तरीका है।

सबसे पहले, मान लें कि मेरे पास एक लाइब्रेरी है जो निम्न परिभाषाओं के साथ सी में बनाई गई थी।

typedef struct { 
    int messageType; 
    BYTE payload[60]; 
} my_message; 

/** 
* \param[out] msg Where the message will be written to 
*/ 
void receiveMessage(my_message *msg); 

/* 
* \param[in] msg The message that will be sent 
*/ 
void sendMessage(my_message *msg); 

सी # में, निम्न संरचना सी

[StructLayout(LayoutKind.Sequential, Size = 64), Serializable] 
struct my_message 
{ 
    int messageType; 
    [MarshalAs(UnmanagedType.ByValArray,SizeConst = 60)] 
    byte[] payload; 

    public initializeArray() 
    { 
     //explicitly initialize the array 
     payload = new byte[60]; 
    } 
} 

में एक receiveMessage (में संदेश के बाद से के बराबर होगा) के रूप में [बाहर], तुम क्या करने की जरूरत नहीं है प्रलेखित है समारोह में इसे पार करने से पहले संरचना में सरणी के लिए विशेष कुछ भी। यानी .:

my_message msg = new my_message(); 
receiveMessage(ref msg); 
byte payload10 = msg.payload[10]; 

के बाद से SendMessage में संदेश() के रूप में [में] प्रलेखित है, तो आप समारोह कॉल करने से पहले सरणी को भरने के लिए की आवश्यकता होगी। सरणी भरने से पहले, सरणी का उपयोग करने से पहले स्पष्ट रूप से तत्काल होना आवश्यक है। यानी .:

my_message msg = new my_message(); 
msg.initializeArray(); 
msg.payload[10] = 255; 
sendMessage(ref msg); 

initializeArray कॉलिंग() इस सरणी के लिए struct के अंदर बनाया पहले से आवंटित अंतरिक्ष में सरणी का दृष्टांत चाहिए।

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