2011-01-19 68 views
0

我是微軟世界的新手。 我有很多的問題,試圖從c#傳遞一個簡單的字符串到dll/C++ 我已經閱讀了大量的文章和文檔,但問題是一樣的。從c#到C++編組字符串

C++代碼

extern "C" __declspec(dllexport) int Init(long l , char* url); 

C#代碼

[DllImport("MCRenderer.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)] 
    public static extern int Init(long a, StringBuilder url); 


Init(hndl.ToInt64(), str); 

是什麼haeppen,長期價值傳遞正確而字符串參數是

0x00000000 <Bad Ptr> 

你可以幫我...蔭真的很困惑 謝謝!! AG

回答

1

您應該傳遞一個字符串,url應該是string類型而不是StringBuilder。

+0

我做了一個快速查找 - StringBuilder的是對於Unicode有用的,所以,可能是它的存在的原因。 – Tesserex 2011-01-19 15:16:08

+0

但如果你把一個字符串它工作? – 2011-01-19 15:18:03

2

這是因爲你編組錯誤:在C#中longint都是(通常)在C#中的int

0

MSDN,您需要:

唯一需要注意的是,StringBuilder的必須爲返回值分配足夠的空間,或文本將溢出,從而導致異常到P/Invoke的拋出

而且從Marshaling between Managed and Unmanaged Code

  • 千萬不要錯過StringBu ilder通過引用(使用out或ref)。否則,CLR會認爲這個參數的簽名是wchar_t **而不是wchar_t *,並且它不能夠綁定StringBuilder的內部緩衝區。性能將顯着降低。
  • 當非託管代碼使用Unicode時,請使用StringBuilder。否則,CLR將不得不復制字符串並在Unicode和ANSI之間進行轉換,從而降低性能。通常您應該將StringBuilder編碼爲Unicode字符的LPARRAY或LPWSTR。
  • 總是提前指定StringBuilder的容量,並確保容量足夠容納緩衝區。非託管代碼端的最佳做法是接受字符串緩衝區的大小作爲參數以避免緩衝區溢出。在COM中,您也可以在IDL中使用size_is來指定大小。

所以,在你的榜樣,你需要指定本機尺寸爲StringBuilder這樣StringBuilder str = new StringBuilder(SIZE_OF_NATIVE_STRING);

0

的參數嘗試在DLL中的函數參數使用LPCSTR

extern "C" __declspec(dllexport) int Init(long l , **LPCTSTR** url); 

這裏一個很好的例子,我發現如何做到這一點。

C++:

extern "C" __declspec(dllexport) void doSomething(LPCTSTR asString) 
{ 
    std::cout << "here" << (wchar_t)asString << endl; 
    system ("pause"); 
} 

C#:

class Program 
{ 
    static void Main(string[] args) 
    { 
     String myString = "String in C#"; 
     doSomething(myString); 
    } 
    private const String path = @"C:\testdll2.dll"; //Make sure that the DLL is in this location 

    [DllImport(path)] 
    private static extern void doSomething(string asString); 
}