2012-10-09 12 views
9

मैं कोडप्रोजेक्ट से एक परियोजना के साथ खेल रहा था जो मूल रूप से कंप्यूटर पर मुद्रण गतिविधि पर नज़र रखता है। हालांकि यह 64 बिट कॉन्फ़िगरेशन के लिए सही तरीके से काम नहीं करता है। कोड का नीचे हिस्सा मुद्दा था। जब भी प्रिंटिंग किया जाता है तो यह कोड कहा जाता है।PRINT_NOTIFY_INFO_DATA को सही ढंग से परिभाषित करने के लिए कैसे करें?

PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));       
int pData = (int)pNotifyInfo + Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO)); 
PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; 
for (uint i = 0; i < info.Count; i++) 
{ 
    data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); 
    pData += Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); 
} 

डीबगिंग से पता चलता है कि डेटा [i] फ़ील्ड मान हमेशा 0 होता है। 32 बिट में हालांकि यह सही तरीके से काम करता है। मुझे लगता है कि PRINTER_NOTIFY_INFO_DATA सही ढंग से परिभाषित नहीं किया गया है। वर्तमान में मैं निम्नलिखित कोड का उपयोग कर रहा हूं। क्या कोई 64 बिट में सही तरीके से काम करने के लिए इसे ठीक कर सकता है?

[StructLayout(LayoutKind.Sequential)] 
public struct PRINTER_NOTIFY_INFO 
{ 
    public uint Version; 
    public uint Flags; 
    public uint Count; 
} 


[StructLayout(LayoutKind.Sequential)] 
public struct PRINTER_NOTIFY_INFO_DATA_DATA 
{ 
    public uint cbBuf; 
    public IntPtr pBuf; 
} 

[StructLayout(LayoutKind.Explicit)] 
public struct PRINTER_NOTIFY_INFO_DATA_UNION 
{ 
    [FieldOffset(0)] 
    private uint adwData0; 
    [FieldOffset(4)] 
    private uint adwData1; 
    [FieldOffset(0)] 
    public PRINTER_NOTIFY_INFO_DATA_DATA Data; 
    public uint[] adwData 
    { 
     get 
     { 
      return new uint[] { this.adwData0, this.adwData1 }; 
     } 
    } 
} 

// Structure borrowed from http://lifeandtimesofadeveloper.blogspot.com/2007/10/unmanaged-structures-padding-and-c-part_18.html. 
[StructLayout(LayoutKind.Sequential)] 
public struct PRINTER_NOTIFY_INFO_DATA 
{ 
    public ushort Type; 
    public ushort Field; 
    public uint Reserved; 
    public uint Id; 
    public PRINTER_NOTIFY_INFO_DATA_UNION NotifyData; 
} 

मैं एमएस एक्सपीएस ड्राइवर का उपयोग कर प्रिंट का परीक्षण कर रहा था। कोड प्रोजेक्ट आलेख Here

उत्तर

14

यह Data Alignment की वजह से 64-बिट कॉन्फ़िगरेशन के लिए सही ढंग से काम नहीं करता है।

तो मैं सुझाव है कि आप PRINTER_NOTIFY_INFO बदलने के लिए इस प्रकार है:

[StructLayout(LayoutKind.Sequential)] 
public struct PRINTER_NOTIFY_INFO 
{ 
    public uint Version; 
    public uint Flags; 
    public uint Count; 
    public PRINTER_NOTIFY_INFO_DATA_UNION aData; 
} 

और फिर Marshal.OffsetOf बजाय Marshal.SizeOf का उपयोग करें:

PRINTER_NOTIFY_INFO info = (PRINTER_NOTIFY_INFO)Marshal.PtrToStructure(pNotifyInfo, typeof(PRINTER_NOTIFY_INFO));       
long pData = (long)pNotifyInfo + (long)Marshal.OffsetOf(typeof(PRINTER_NOTIFY_INFO), "aData"); 
PRINTER_NOTIFY_INFO_DATA[] data = new PRINTER_NOTIFY_INFO_DATA[info.Count]; 
for (uint i = 0; i < info.Count; i++) 
{ 
    data[i] = (PRINTER_NOTIFY_INFO_DATA)Marshal.PtrToStructure((IntPtr)pData, typeof(PRINTER_NOTIFY_INFO_DATA)); 
    pData += (long)Marshal.SizeOf(typeof(PRINTER_NOTIFY_INFO_DATA)); 
} 
+0

तुम मेरी जान बचाई, एक लाख thanx। –

+0

इसके अतिरिक्त, सुनिश्चित करें कि शामिल परियोजनाएं x86 निष्पादन योग्य बनाने के लिए कॉन्फ़िगर की गई हैं !!! –

+0

इस पर ध्यान देने के लिए चीजों का जोड़ा। 1) मार्शल.ऑफसेटऑफ() एक इंटिप्ट ऑब्जेक्ट देता है, जो मेरे ज्ञान के लिए सीधे लंबे समय तक नहीं डाला जा सकता है। आपको IntPtr.ToInt32() विधि का उपयोग करना होगा। 2) यह कोड संभावित रूप से आपके कोड को क्रैश कर सकता है यदि PRINTER_NOTIFY_INFO.Count 0 है। इसका मतलब यह होगा कि डेटा [] सूची में कोई संरचना नहीं है। इसे वर्णित तरीके से घोषित करके, आप सरणी में कम से कम 1 ऑब्जेक्ट की गारंटी दे रहे हैं। यदि गिनती 0 है, तो उस संभावित सेगमेंटेशन गलती की तुलना में। मैं एडाटा को इंटिप्ट के रूप में घोषित करता हूं, क्योंकि वास्तव में, अप्रबंधित कोड में यह सिर्फ एक सूचक है। – Ultratrunks

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

  • कोई संबंधित समस्या नहीं^_^