2012-05-29 7 views
15

मैं एक लंबे समय के लिए ++ करने के लिए/सी # से करने के लिए/सी से एक स्ट्रिंग भेजने की कोशिश कर दिया गया है लेकिन यह अभी तक काम कर पाने के प्रबंधन नहीं किया ...DLLImport का उपयोग कर सी # से सी ++ (और सी ++ से सी # तक) तारों को कैसे पारित करें?

तो मेरे सवाल का सरल है:
किसी को भी करता है सी # से सी ++ और सी ++ से सी # तक स्ट्रिंग भेजने के लिए कुछ तरीका जानें?
(कुछ नमूना कोड सहायक होंगे)

उत्तर

9

सी सी # से स्ट्रिंग पासिंग ++ सीधे आगे होना चाहिए। PInvoke आपके लिए रूपांतरण का प्रबंधन करेगा।

सी ++ से सी # तक स्ट्रिंग प्राप्त करना स्ट्रिंगबिल्डर का उपयोग करके किया जा सकता है। सही आकार के बफर को बनाने के लिए आपको स्ट्रिंग की लंबाई प्राप्त करने की आवश्यकता है।

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); 
public static string GetText(IntPtr hWnd) 
{ 
    // Allocate correct string length first 
    int length  = GetWindowTextLength(hWnd); 
    StringBuilder sb = new StringBuilder(length + 1); 
    GetWindowText(hWnd, sb, sb.Capacity); 
    return sb.ToString(); 
} 


[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
public static extern bool SetWindowText(IntPtr hwnd, String lpString); 
SetWindowText(Process.GetCurrentProcess().MainWindowHandle, "Amazing!"); 
1

विंडोज एपीआई में कई सारे फ़ंक्शन स्ट्रिंग या स्ट्रिंग-प्रकार पैरामीटर लेते हैं। इन मानकों के लिए स्ट्रिंग डेटा प्रकार का उपयोग करने में समस्या यह है कि .NET में स्ट्रिंग डेटाटाइप एक बार बनाया जाने वाला अपरिवर्तनीय है, इसलिए स्ट्रिंगबिल्डर डेटाटाइप सही विकल्प है। एक उदाहरण के लिए जांच एपीआई समारोह GetTempPath()

Windows API परिभाषा

DWORD WINAPI GetTempPath(
    __in DWORD nBufferLength, 
    __out LPTSTR lpBuffer 
); 

नेट प्रोटोटाइप

[DllImport("kernel32.dll")] 
public static extern uint GetTempPath 
(
uint nBufferLength, 
StringBuilder lpBuffer 
); 

प्रयोग

const int maxPathLength = 255; 
StringBuilder tempPath = new StringBuilder(maxPathLength); 
GetTempPath(maxPathLength, tempPath); 
13

अपने ग कोड में:

extern "C" __declspec(dllexport) 
int GetString(char* str) 
{ 
} 

extern "C" __declspec(dllexport) 
int SetString(const char* str) 
{ 
} 

.net पक्ष में:

using System.Runtime.InteropServices; 


[DllImport("YourLib.dll")] 
static extern int SetString(string someStr); 

[DllImport("YourLib.dll")] 
static extern int GetString(StringBuilder rntStr); 

उपयोग:

SetString("hello"); 
StringBuilder rntStr = new StringBuilder(); 
GetString(rntStr); 
+1

आपका 'const' उपयोग पीछे की ओर है:

यहाँ एक अच्छी तरह से ज्ञात Win32 एपीआई के दो उदाहरण हैं। –

+0

@ बेन वोगेट: धन्यवाद, इसे ठीक किया गया। – sithereal

+0

इन उदाहरणों में VisStudio 2012 में स्टैक अपवादों के साथ विस्फोट हुआ जब तक कि मैंने सी # और सी दोनों को सीडीसीएल जोड़ा। बाहरी "सी" __declspec (dllexport) int __cdecl SetString (... और फिर ... [DllImport (" YourLib.dlll ", कॉलिंग कन्वेंशन = कॉलिंग कन्वेंशन.सीडीसीएल)] ... – user922020

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