2013-07-10 5 views
6

मैं हस्ताक्षरएक संरचना में IntPtr कैसे प्राप्त करें?

public int Copy(Texture texture, Rect? srcrect, Rect? dstrect) 

Rect के साथ एक विधि मिल गया है एक struct है, लेकिन मैं फोन करने वाले के रूप में अच्छी तरह से करने के लिए विधि null (या IntPtr.Zero) पारित करने के लिए अनुमति देने के लिए की जरूरत है।

मैं तो यह हस्ताक्षर

[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")] 
internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect); 

मुझे उम्मीद थी मैं निम्नलिखित की तरह कुछ कर सकता है के साथ एक DLL के लिए रवाना पास करना चाहते हैं:

return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero); 

लेकिन मैं struct डाली नहीं कर सकता उसके जैसा। क्या कोई और तरीका है जिससे मैं IntPtr प्राप्त कर सकता हूं?

  • ref Rect, ref Rect
  • IntPtr, IntPtr
  • ref Rect, IntPtr
  • IntPtr, ref Rect

जो मिल सकता है:


वहाँ

विकल्प 4 भार के बनाने के लिए है अगर मुझे कभी भी 2 से अधिक संरचना पॉइंटर्स पास करने की आवश्यकता है तो भी गड़बड़।


मैं एक समाधान के साथ आया था, लेकिन मैं इसके बारे में कुछ सवाल हैं:

public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null) 
{ 
    return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? StructToPtr(srcrect) : IntPtr.Zero, dstrect.HasValue ? StructToPtr(dstrect) : IntPtr.Zero); 
} 

private static IntPtr StructToPtr(object obj) 
{ 
    var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); 
    Marshal.StructureToPtr(obj, ptr, false); 
    return ptr; 
} 

था मैं ref Rect इस्तेमाल किया मैं struct के लिए स्मृति को आबंटित करने के लिए किया था नहीं होता - क्या करता है इससे अलग करते हैं?


मैंने कुछ प्रयोग किया था। ref Rect समाधान एक Rect एक IntPtr को बदलने रूप में एक ही गति एक Rect के लिए एक IntPtr पैदा करने, जो मुझे सुराग शक करने के लिए कि सी # हुड जब आप refs का उपयोग के तहत बहुत कुछ इसी तरह कर रही है के बारे में कम से चलाता है। जैसे ही मैं इसे Rect? बना देता हूं और उस विधि को सशर्त तर्क जोड़ता हूं जो 50% तक धीमा हो जाता है ... इसलिए 4-अधिभार मार्ग शायद सबसे तेज़ होगा। हालांकि, हम 100 के पुनरावृत्तियों के लिए 100-150ms बात कर रहे हैं, जिसका मतलब है कि विधि स्वयं ही सस्ता है, शायद यही कारण है कि सशर्तों का इतना उल्लेखनीय प्रभाव पड़ता है। इस प्रकार, मैं अपने कस्टम StructToPtr समाधान के साथ चिपक रहा हूं क्योंकि यह सबसे आसान समाधान है।

+0

आपका शीर्षक खराब शब्द है। आप एक स्ट्रक्चर को इंटिप्टर में परिवर्तित नहीं कर सकते हैं। हालांकि, आप एक संरचना के लिए एक सूचक प्राप्त कर सकते हैं। –

+0

@ जिम मिशेल: सच। मैं वास्तव में इसे "रूपांतरित करने" के बारे में सोच नहीं रहा था, मैं एक कलाकार की तरह कुछ के बारे में सोच रहा था; सी में आप अपना पता प्राप्त करने के लिए एक चर से पहले '& 'थप्पड़ मार सकते हैं। – mpen

उत्तर

7

आप Marshal.StructureToPtr का उपयोग करना चाहते हैं।

आपको संरचना के लिए स्मृति आवंटित और आवंटित करना होगा।

विषय पर एक अच्छा ब्लॉग http://www.developerfusion.com/article/84519/mastering-structs-in-c/

+0

इसे 3 पैरामीटर की आवश्यकता है। ऐसा लगता है कि मुझे इसके लिए स्मृति को पूर्ववत करना है। – mpen

+0

हाँ, इसके बारे में खेद है। मैंने जवाब संपादित किया और आपको एक ब्लॉग पर इंगित किया। –

+0

क्या कुछ और खोज किया गया और मुझे लगता है कि एक बेहतर समाधान http://stackoverflow.com/questions/1049623/how-to-pass-a-nullable-type-to-ap-invoked-function –

-2

यहाँ पर पाया जा सकता है कि मैं क्या है, मैं एक एम $ DLL से एक एपीआई का उपयोग कर रहा हूँ और प्रोटोटाइप इस तरह है:

HRESULT C_API(LPCWSTR name, PSTRUCT_WHATEVER *ppStruct); 

संरचना इस तरह के रूप में परिभाषित किया जाता है:

:

typedef struct whatever { 
    LPCWSTR x; 
    LPCWSTR y; 
} 

सी # में मैं निम्नलिखित को परिभाषित कर रहा हूँ इस बिंदु mystring = "इस एक स्ट्रिंग है" पर

IntPtr s;   
long HR = C_API("myname", out s); 

WHATEVER pInfo = (WHATEVER) Marshal.PtrToStructure(s, typeof(WHATEVER)); 

String mystring = Marshal.PtrToStringAuto(pInfo.x); 

;:

इसका इस्तेमाल करने के लिए

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