2011-01-03 12 views
6

ठीक है दोस्तों, यह मुझे पागल बना रहा है। मैं सी # में सी सीबी के लिए एक पोर्ट बना रहा हूं लेकिन मुझे एक बाइट सरणी (सीबीबी से आवश्यक) के साथ बिटमैप (जीडीआई के साथ जेनरेट) का उपयोग करने में समस्या हैसी # के लिए सी # .नेट रैपर, विशेष रूप से lglcd (g19 sdk)

यहां कोड है, (pastie) फ़ाइलों में विभाजित:

  1. Lglcd.dll: http://pastie.org/1424596 (संकलित)
  2. G19dotNet.dll: http://pastie.org/1424600 (संकलित, इस ग # के लिए इंटरॉप lib)
  3. TestProject है: http://pastie.org/1424603 (संकलन, लेकिन एक अपवाद फेंकता)

समस्या पिछले फ़ाइल (अन्य दो बिल्कुल स्पष्ट कर रहे हैं) में है, लाइन 116

res = LgLcd.NativeMethods.lgLcdUpdateBitmap(openContext.device, ref bmp.hdr, LgLcd.NativeConstants.LGLCD_SYNC_UPDATE(LgLcd.NativeConstants.LGLCD_PRIORITY_NORMAL)); 

यह एक अमान्य स्मृति पहुँच के लिए एक अपवाद फेंकता प्रबंधित स्मृति के लिए।

समारोह के हस्ताक्षर इस एक है:

/// Return Type: DWORD->unsigned int 
      ///device: int 
      ///bitmap: lgLcdBitmapHeader* 
      ///priority: DWORD->unsigned int 
      [System.Runtime.InteropServices.DllImportAttribute("LgLcd", EntryPoint = "lgLcdUpdateBitmap")] 
      public static extern uint lgLcdUpdateBitmap([System.Runtime.InteropServices.In] int device, [System.Runtime.InteropServices.In] ref lgLcdBitmapHeader bitmap, [System.Runtime.InteropServices.In] uint priority); 

आप दूसरी परम देख सकते हैं lgLcdBitmapHeader करने के लिए एक सूचक है, लेकिन मुझे लगता है कि (क्योंकि मैं lib के एक पुराने संस्करण देखा है) कि इस सूचक एक lgLcdBitmapQVGAx32 सूचक

मुझे लगता है कि समस्या है है (जो विभिन्न आकार के एक struct हो) पर casted है, फिर भी मैं, इस को हल करने के प्रबंधन नहीं कर सकते वास्तव में

यहाँ

struct के हस्ताक्षर है :

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
    public struct lgLcdBitmapHeader 
    { 

     /// DWORD->unsigned int 
     public uint Format; 
    } 

और

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
    public struct lgLcdBitmap160x43x1 
    { 

     /// lgLcdBitmapHeader->Anonymous_5fa96ca7_9cc3_4b33_b5aa_ccff9833813a 
     public lgLcdBitmapHeader hdr; 

     /// BYTE[] 
     //public fixed byte pixels[NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP]; 
     [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP)] 
     public byte[] pixels; 
     public static int SizeConst { get { return NativeConstants.LGLCD_BMP_WIDTH * NativeConstants.LGLCD_BMP_HEIGHT * NativeConstants.LGLCD_BMP_BPP; } } 
    } 

मुझे आशा है कि कोई मेरी मदद कर सकते हैं, मैं वेब पर देख रहा हूं और मैं इस lib की एक .net बंदरगाह मिल गया है, लेकिन यह बहुत पुरानी है, और नहीं है मेरे पास समस्या है क्योंकि रंगीन बिटमैप्स (प्रत्येक रंग के लिए 4 बाइट्स के साथ) का उपयोग नहीं करता है और lgLcdBitmapHeader संरचना का उपयोग नहीं करता है (यह एक सरल उपयोग करता है)। इसके अलावा यह स्रोत कोड मेरे जैसा ही है।

http://lglcdnet.codeplex.com/SourceControl/changeset/changes/5538

अद्यतन: 1:

किसी भी मदद

उपयोगी लिंक्स की सराहना की जाएगी

मैं एक teory के आधार पर कुछ प्रगति किया था।

DWORD WINAPI lgLcdUpdateBitmap(IN int device, 
          IN const lgLcdBitmapHeader *bitmap, 
          IN DWORD priority); 

यह हस्ताक्षर, "एक अर्थ" ग में है, क्योंकि एक struct के पहले तत्व के लिए सूचक भी है कि struct करने के लिए सूचक है। वास्तव में lgLcdBitmapQVGAx32 में lgLcdBitmapHeader प्रकार का पहला तत्व है। ने कहा कि, वे "जेनेरिक विधि" बनाने के लिए सब कुछ सब कुछ करने के लिए सी की संभावना का उपयोग कर रहे हैं, क्योंकि lgLcdBitmapHeader lgLcdBitmap160x43x1 (पहला elem lgLcdBitmapHeader) या lgLcdBitmapQVGAx32 दोनों हो सकता है।

इसका कारण यह है सी # में मैं इस क्षमता का अनुकरण नहीं कर सकते हैं एक समस्या है, इसलिए मैं कुछ "सहायक" कार्य करता है जो lgLcdBitmap160x43x1 और lgLcdBitmapQVGAx32 जो आंतरिक रूप से lgLcdBitmapHeader की ओर इशारा कर रहे हैं के रूप में इस्तेमाल स्वीकार बनाया।

यह किया है, तथापि, मुझे एक और त्रुटि दिया:

System.Runtime.InteropServices.MarshalDirectiveException non è stata gestita 
    Message=Impossibile effettuare il marshalling di 'parameter #2': Limitazione interna: la struttura è troppo complessa o troppo grande. 
    Source=G19dotNet 
    StackTrace: 
     in G19dotNet.LgLcd.NativeMethods.lgLcdUpdateBitmapQVGAx32(Int32 device, lgLcdBitmapQVGAx32& bitmap, UInt32 priority) 
     in ConsoleTest2.Program.Main(String[] args) in C:\Documents and Settings\Administrator\documenti\visual studio 2010\Projects\G19dotNet\ConsoleTest2\Program.cs:riga 116 
     in System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     in System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     in Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     in System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     in System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     in System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     in System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
System.Runtime.InteropServices.MarshalDirectiveException गैर नौकरी STATA gestita संदेश = impossibile effettuare इल मार्शलिंग di 'पैरामीटर # 2' की

अंग्रेजी संस्करण: Limitazione interna: la struttura è troppo complessa o troppo grande।:

System.Runtime.InteropServices.MarshalDirectiveException संभाला नहीं संदेश = असंभव का पैरामीटर # 2 'प्राथमिकता निर्धारण करते हैं: आंतरिक सीमा: संरचना बहुत बड़ी या बहुत जटिल है

यह की एक सरणी है 307200 बाइट्स, मुझे क्या करना चाहिए?

अद्यतन 2:

मैं अपनी स्क्रीन पर एक छवि दिखाने में कामयाब रहे, इसका मतलब है कि मेरी teory सही था, मैं यह काम करता है बनाने के लिए "बात" के इस प्रकार का उपयोग करने के लिए किया था: http://bytes.com/topic/c-sharp/answers/272048-internal-limitation-structure-too-complex-too-large हालांकि छवि दिखाया गया है "टूटा हुआ", मेरा मतलब है कि इसमें मूल छवि का आकार है लेकिन थोड़ा उलझन और बेकार है, शायद क्योंकि मैं बिटमैप कैसे पास करता हूं?

अद्यतन 3 और समाधान:

मैं अपने आप को द्वारा समस्या हल, कोड वास्तव में बदसूरत है और मैं इसे यहाँ pastie अंदर पोस्ट करेंगे, उम्मीद है कि किसी को यह उपयोगी मिल जाएगा।

/// <summary> 
/// LONG GetBitmapBits(
/// __in HBITMAP hbmp, 
/// __in LONG cbBuffer, 
/// __out LPVOID lpvBits 
/// ); 
/// </summary> 
/// <param name="hbmp"></param> 
/// <param name="cbBuffer"></param> 
/// <param name="lpvBits"></param> 
/// <returns></returns> 
[DllImport("Gdi32", EntryPoint = "GetBitmapBits")] 
public extern static long GetBitmapBits([In] IntPtr hbmp,[In] int cbBuffer,[Out] byte[] lpvBits); 

[DllImport("Gdi32", EntryPoint = "GdiFlush")] 
public extern static void GdiFlush(); 

public static void FillPixelArray3(Bitmap bmp, ref byte[] array) 
{ 
    IntPtr hbmp = bmp.GetHbitmap(); 

    GdiFlush(); 
    //Marshal SizeOf is to "ensure" that other people will notice that array.Length 
    //must be multiplied 
    GetBitmapBits(hbmp, array.Length * Marshal.SizeOf(typeof(byte)), array); 

} 

और इस:

IntPtr unhandledPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LgLcd.lgLcdBitmapQVGAx32))); 
    Marshal.StructureToPtr(bmp, unhandledPtr, true); 
    res = LgLcd.NativeMethods.lgLcdUpdateBitmap(openContext.device, unhandledPtr, LgLcd.NativeConstants.LGLCD_SYNC_UPDATE(LgLcd.NativeConstants.LGLCD_PRIORITY_NORMAL)); 
    Marshal.FreeHGlobal(unhandledPtr); 
+0

शायद तुम इसे पारित करने से पहले एक संयुक्त राष्ट्र से प्रबंधित प्रकार में कुछ मार्शल करने के लिए है? – Machinarius

+0

यह निश्चित रूप से है, हालांकि मुझे नहीं पता कि इस तरह मार्शल कैसे करें, मैं इंटरऑप सेवाओं के साथ अच्छा नहीं हूं, मैं पागल हो रहा हूं –

+0

मुझे यकीन नहीं है, लेकिन क्या आप http: // msdn पर एक नज़र डाल सकते हैं .microsoft.com/en-us/library/23acw07k.aspx –

उत्तर

1

अप्रबंधित आवंटन का उपयोग सीधे प्रश्न में समझाया गया है।

कोड उदाहरण:

IntPtr unhandledPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(LgLcd.lgLcdBitmapQVGAx32))); 
Marshal.StructureToPtr(bmp, unhandledPtr, true); 
res = LgLcd.NativeMethods.lgLcdUpdateBitmap(openContext.device, unhandledPtr, LgLcd.NativeConstants.LGLCD_SYNC_UPDATE(LgLcd.NativeConstants.LGLCD_PRIORITY_NORMAL)); 
Marshal.FreeHGlobal(unhandledPtr); 

इसके अलावा, मैं निर्वासन विधि हस्ताक्षर बदलने के लिए की जरूरत:

[DllImportAttribute("LgLcd", EntryPoint = "lgLcdUpdateBitmap")] 
    public static extern uint lgLcdUpdateBitmap([In] int device, [In] IntPtr bitmap, [In] uint priority); 
    //OLD ONE: 
    public static extern uint lgLcdUpdateBitmap([In] int device, [In] ref lgLcdBitmapHeader bitmap, [In] uint priority); 
0

जब से तुम ग dll के लिए स्रोत कोड है, तो आप विजुअल C++ CLR परियोजना के साथ आवरण लिखने पर विचार करना चाहिए कोड का सबसे महत्वपूर्ण हिस्सा यह एक है । सामान्य भाषा रनटाइम आपको एक साथ प्रबंधित और अप्रबंधित कोड लिखने की अनुमति देता है। फिर आपको चर को पारित करने की आवश्यकता नहीं है लेकिन उन्हें सीधे उपयोग करें।

और जब आप इसे सी # से उपयोग करना चाहते हैं तो बस अपने सी # एप से सी ++ क्लियर लाइब्रेरी का संदर्भ लें। मैंने पहले इस तरह इस्तेमाल किया और यह पूरी तरह से काम करता है।

+0

मुझे लगता है कि यह बेहतर है लेकिन कभी भी C++ clr का उपयोग नहीं किया गया, हालांकि मैं कुछ दिखाने में कामयाब रहा, समस्या अब बिटमैप को सही ढंग से दिखा रही है –

+0

@Fire: ठीक है तो मुझे लगता है कि आपको चाहिए पिक्सेल प्रारूप देखें। हमारे पास पीएफ 32bppARGB है, पीएफ 32bppRGBA ... क्या यह संभव है कि आप हरे रंग के बजाय अल्फा मान देखें? – honibis

+0

एमएच मैं इसे एक अलग तरीके से काम करने में कामयाब रहा, मैं PBvoked GetBitmapBits जो एचबीआईटीएमएपी के साथ अच्छी तरह से काम करता है, मैं आसानी से इसे अपने बिटमैप से प्राप्त कर सकता हूं ... तो सब ठीक है, मुझे लगता है कि यह भी इस तरह ठीक है। बीटीडब्ल्यू प्रारूप आरजीबीए है –