2008-11-14 7 views
20

उदाहरण सी एपीआई हस्ताक्षर:सी # में पी/इनवॉक का उपयोग करके मैं एक सरणी में पॉइंटर कैसे पास कर सकता हूं?

void Func(unsigned char* bytes);

सी में, जब मैं एक सरणी के लिए एक सूचक पास करना चाहते हैं, मैं कर सकते हैं:

unsigned char* bytes = new unsigned char[1000]; 
Func(bytes); // call 

मैं कैसे पी करने के लिए ऊपर एपीआई अनुवाद नहीं करते/इस तरह से आमंत्रित करें कि मैं एक सूचक को सी # बाइट सरणी में पास कर सकता हूं?

उत्तर

31

बाइट्स की सरणी को पार करने का सबसे आसान तरीका है अपने आयात विवरण में बाइट सरणी के रूप में पैरामीटर घोषित करना।

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true] 
public extern static void Func(byte[]); 

byte[] ar = new byte[1000]; 
Func(ar); 

तुम भी एक IntPtr के रूप में पैरामीटर घोषित करने और मैन्युअल रूप से डेटा मार्शल करने के लिए सक्षम होना चाहिए।

[DllImport EntryPoint="func" CharSet=CharSet.Auto, SetLastError=true] 
public extern static void Func(IntPtr p); 

byte[] ar = new byte[1000]; 
IntPtr p = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(byte)) * ar.Length); 
Marshal.Copy(ar, 0, p, ar.Length); 
Func(p); 
Marshal.FreeHGlobal(p); 
+0

पहला दृष्टिकोण क्यों काम करेगा, और दूसरा काम नहीं करेगा। विंडोज़ ऐप पर मैं यही सामना कर रहा हूं। – moubarak

+1

मुझे पता है कि यह पोस्ट थोड़ा पुराना है लेकिन 'मार्शल .इज़ऑफ (ऑब्जेक्ट)' सरणी के साथ काम नहीं करता है। मुझे पूरा यकीन है कि अगर आप इसे एक सरणी पास करते हैं तो आपको अपवाद मिलेगा लेकिन मेरे पास अभी कोशिश करने के लिए मेरे सामने वीएस खुला नहीं है। किसी सरणी के आकार को सही ढंग से निर्धारित करने के लिए, आपके उदाहरण के लिए कोड 'मार्शल। सिज़ऑफ (टाइपोफ (बाइट)) * ar.Length' होगा। – 9ee1

+0

हां, आप सही 9 1 हैं। मार्शल.SizeOf एक संरचना के लिए इस्तेमाल किया जा सकता है लेकिन एक सरणी नहीं। मैंने तदनुसार उदाहरण कोड अपडेट किया है। धन्यवाद। – asponge

6

आप असुरक्षित कोड का उपयोग कर सकते हैं: हालांकि, सुरक्षित कोड धीमी IMHO होने जा रहा है

IntPtr intPtr = Marshal.AllocHGlobal(Marshal.SizeOf(byteArray)); 
Marshal.Copy(byteArray, 0, intPtr, Marshal.SizeOf(byteArray)); 

Func(intPtr); 

Marshal.FreeHGlobal(intPtr); 

: आप, आप कुछ चाल का उपयोग कर सकते सुरक्षित कोड का उपयोग करने की जरूरत है

unsafe 
{ 
    fixed(byte* pByte = byteArray) 
    IntPtr intPtr = new IntPtr((void *) pByte); 
    Func(intPtr); 
} 

3

यहां मूल कार्य के लिए उपयुक्त हस्ताक्षर है।

[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="Func")] 
public static extern void Func(System.IntPtr bytes) ; 
संबंधित मुद्दे

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