2011-12-12 13 views
5

मैं सी # के साथ एक अप्रबंधित संसाधन के साथ काम कर रहा हूं। संसाधन कॉलबैक का खुलासा करता है जो हार्डवेयर के भीतर होने वाली कुछ घटनाओं के लिए सेटअप किया जा सकता है। अप्रबंधित कार्यों मैं निम्न करने के लिए पहुँच प्राप्त करने के लिए:अप्रबंधित कॉलबैक के कारण स्टैक ओवरफ्लो

[DllImportAttribute("testDLL.dll", EntryPoint = "InstallCallback")] 
public static extern short InstallCallback(uint handle, byte x, byte y, IntFuncPtr ptr); 

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
public delegate void IntFuncPtr(uint handle, byte x, byte y, LogEntry info); 

मैं पहली बार एक विधि है कि IntFuncPtr प्रतिनिधि इस प्रकार के लिए एक संदर्भ के साथ कॉलबैक स्थापित करें। मैं हार्डवेयर को अपनी बात करने देता हूं। कॉलबैक की लगभग 4700 कॉल के बाद एप्लिकेशन क्रैश हो गया। अगर मैं c/C++ में कोड लिखता हूं तो कॉलबैक ठीक काम करता है, हालांकि मैं अपने कॉलबैक फ़ंक्शन से __stdcall को हटाकर इसे दोहरा सकता हूं। सी # से मैं त्रुटि नहीं पकड़ सकता जो इंगित करता है कि एप्लिकेशन अप्रबंधित संसाधन में मर रहा है। सी/सी ++ एप्लिकेशन के साथ मैं देख सकता हूं कि स्टैक ओवरफ्लो बिना __stdcall के।

मैंने सोचा था कि प्रतिनिधि बुला सम्मेलन के साथ काम नहीं कर सकते stdcall तो मैं निम्नलिखित की कोशिश की:

[DllImportAttribute("testDLL.dll", EntryPoint = "InstallCallback")] 
public static extern short InstallCallback(uint handle, byte x, byte y, IntPtr ptr); 

public delegate void IntFuncPtr(uint handle, byte x, byte y, LogEntry info); 

var callBackDelegate = new IntFuncPtr(Callback); 
var callBackPtr = Marshal.GetFunctionPointerForDelegate(callBackDelegate); 
InstallCallback(handle, 1, 1, callBackPtr); 

यह भी काम नहीं किया।

संक्षेप में, मेरे पास एक अप्रबंधित कॉलबैक है जिसके लिए एक __stdcall के रूप में परिभाषित फ़ंक्शन के लिए फ़ंक्शन पॉइंटर की आवश्यकता होती है। यदि फ़ंक्शन पॉइंटर एक गैर __stdcall फ़ंक्शन के लिए है तो स्टैक बढ़ता है और बहती है। मैं ddImport का उपयोग कर सी # में कॉलबैक और stmcall कॉलिंग सम्मेलन के साथ एक अप्रबंधित फ़ंक्शनक्शन प्रतिनिधि प्रतिनिधि का उपयोग करने का प्रयास कर रहा हूं। जब मैं ऐसा करता हूं तो सी # एप्लिकेशन एक सी/सी ++ एप्लिकेशन की तरह कार्य करता है जो गैर __stdcall फ़ंक्शन का उपयोग करता है।

मैं इसे सी # में पूरी तरह से काम करने के लिए कैसे प्राप्त कर सकता हूं?

संपादित करें 1:

यहाँ सी # संरचना की जानकारी सहित देशी विधि परिभाषा & संरचना की जानकारी है।

extern "C" __declspec(dllexport) short __stdcall InstallCallback(unsigned int handle, unsigned char x, unsigned char y, LOG_ENTRY info); 

typedef union 
{ 
    unsigned int ul_All; 
    struct 
    { 
    unsigned int ul_Info:24; 
    unsigned int uc_IntType:8; 
    }t; 

    struct 
    { 
    unsigned int ul_Info:24; 

    unsigned int uc_Biu1:1; 
    unsigned int uc_Biu2:1; 
    unsigned int uc_Dma:1; 
    unsigned int uc_Target:1; 
    unsigned int uc_Cmd:1; 
    unsigned int uc_Biu3:1; 
    unsigned int uc_Biu4:1; 
    unsigned int res:1; 
    }b; 
} LOG_ENTRY_C; 

typedef union 
{ 
    unsigned int All; 
    struct 
    { 
    AiUInt32 Index:16; 
    AiUInt32 Res:8; 
    AiUInt32 IntSrc:8; 
    }t; 
} LOG_ENTRY_D; 

typedef struct log_entry 
{ 
    unsigned int a; 
    unsigned int b; 
    LOG_ENTRY_C c; 
    LOG_ENTRY_D d; 
} LOG_ENTRY; 

[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct LogEntry { 
    public uint Lla; 
    public uint Llb; 
    public LogEntryC Llc; 
    public LogEntryD Lld; 
} 

[StructLayoutAttribute(LayoutKind.Explicit)] 
public struct LogEntryC { 
    [FieldOffsetAttribute(0)] 
    public uint All; 
    [FieldOffsetAttribute(0)] 
    public LogEntryCT t; 
    [FieldOffsetAttribute(0)] 
    public LogEntryCB b; 
} 

[StructLayoutAttribute(LayoutKind.Explicit)] 
public struct LogEntryD { 
    [FieldOffsetAttribute(0)] 
    public uint All; 
    [FieldOffsetAttribute(0)] 
    public LogEntryDT t; 
} 

[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct LogEntryCT { 
    public uint bitvector1; 
    public uint IntType { 
     get { return ((uint)((this.bitvector1 & 255u))); } 
     set { this.bitvector1 = ((uint)((value | this.bitvector1))); } 
    } 
    public uint Info { 
     get { return ((uint)(((this.bitvector1 & 4294967040u)/256))); } 
     set { this.bitvector1 = ((uint)(((value * 256) | this.bitvector1))); } 
    } 
} 
[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct LogEntryCB { 
    public uint bitvector1; 
    public uint res { 
     get { return ((uint)((this.bitvector1 & 1u))); } 
     set { this.bitvector1 = ((uint)((value | this.bitvector1))); } 
    } 
    public uint Biu4 { 
     get { return ((uint)(((this.bitvector1 & 2u)/2))); } 
     set { this.bitvector1 = ((uint)(((value * 2) | this.bitvector1))); } 
    } 
    public uint Biu3 { 
     get { return ((uint)(((this.bitvector1 & 4u)/4))); } 
     set { this.bitvector1 = ((uint)(((value * 4) | this.bitvector1))); } 
    } 
    public uint Cmd { 
     get { return ((uint)(((this.bitvector1 & 8u)/8))); } 
     set { this.bitvector1 = ((uint)(((value * 8) | this.bitvector1))); } 
    } 
    public uint Target { 
     get { return ((uint)(((this.bitvector1 & 16u)/16))); } 
     set { this.bitvector1 = ((uint)(((value * 16) | this.bitvector1))); } 
    } 
    public uint Dma { 
     get { return ((uint)(((this.bitvector1 & 32u)/32))); } 
     set { this.bitvector1 = ((uint)(((value * 32) | this.bitvector1))); } 
    } 
    public uint Biu2 { 
     get { return ((uint)(((this.bitvector1 & 64u)/64))); } 
     set { this.bitvector1 = ((uint)(((value * 64) | this.bitvector1))); } 
    } 
    public uint Biu1 { 
     get { return ((uint)(((this.bitvector1 & 128u)/128))); } 
     set { this.bitvector1 = ((uint)(((value * 128) | this.bitvector1))); } 
    } 
    public uint Info { 
     get { return ((uint)(((this.bitvector1 & 4294967040u)/256))); } 
     set { this.bitvector1 = ((uint)(((value * 256) | this.bitvector1))); } 
    } 
} 

[StructLayoutAttribute(LayoutKind.Sequential)] 
public struct LogEntryDT { 
    public uint bitvector1; 
    public uint IntSrc { 
     get { return ((uint)((this.bitvector1 & 255u))); } 
     set { this.bitvector1 = ((uint)((value | this.bitvector1))); } 
    } 
    public uint Res { 
     get { return ((uint)(((this.bitvector1 & 65280u)/256))); } 
     set { this.bitvector1 = ((uint)(((value * 256) | this.bitvector1))); } 
    } 
    public uint Index { 
     get { return ((uint)(((this.bitvector1 & 4294901760u)/65536))); } 
     set { this.bitvector1 = ((uint)(((value * 65536) | this.bitvector1))); } 
    } 
} 
+0

आप जांच की है कि आपका प्रतिनिधि कचरा एकत्र, एक समारोह अब मौजूद नहीं है कॉल करने के लिए अपने अप्रबंधित कोड के कारण नहीं किया गया है निर्दिष्ट करने के लिए कोशिश की? – tinman

+0

मैं अब यह सत्यापित कर रहा हूं। कॉलबैक लगभग ~ 4700 कॉल के लिए काम करता है और यह लगातार उस संख्या के आसपास है। मेरा मानना ​​है कि अगर यह एक जीसी मुद्दा था तो यह इतना संगत नहीं होगा। एक बार मैंने कुछ और परीक्षण चलाने के बाद एक अपडेट दिया होगा। – Lux782

उत्तर

1

एक स्मृति रिसाव समस्या माना जाता है। क्या आपको पता है कि आपको प्राप्त वस्तुओं से संबंधित किसी भी स्मृति को मुक्त करने की आवश्यकता है (जैसे LogEntry)?

मेरे पास एक समान परिदृश्य है जहां मुझे अपनी कॉलबैक विधि में पारित हर वस्तु की स्मृति को मुक्त करने की आवश्यकता है।

अपने सी # कोड की समीक्षा करें और यह पता लगाने की कोशिश करें कि आप सी/सी ++ से अलग क्या कर रहे हैं।

+0

मैंने एक उत्तर के रूप में पोस्ट किया क्योंकि मैं अभी तक टिप्पणी नहीं कर सकता। अगर मुझे इस जवाब में 5 वोट मिलते हैं तो मैं टिप्पणी कर पाऊंगा :-) –

+0

LogEntry संरचना के लिए कोई क्लीनअप आवश्यक नहीं है। – Lux782

0

आप स्पष्ट रूप से बुला सम्मेलन

[DllImportAttribute("testDLL.dll", EntryPoint = "InstallCallback", CallingConvention=CallingConvention.StdCall) ] 
+0

मैंने इसे भी आजमाया। – Lux782