2010-10-19 61 views
7

我有一個非託管C++ DLL,我需要從Windows Mobile C#應用程序調用。將C#字符串傳遞給Windows Mobile中的非託管C DLL

我有C#包裝,它在桌面上很好地工作。我可以從C#桌面程序調用DLL函數並傳遞字符串,沒有任何問題。

但是,當我編譯移動平臺的lib和包裝器時,我在DllImport行中發現錯誤,表示CharSet.ANSI無法識別。我被允許編寫的唯一選項是CharSet.Auto和CharSet.Unicode。

問題是,不管這個設置如何,在C++函數中接收到的字符串都是寬字符串,而不是簡單的char *字符串,這正是他們所期望的。

我們可以使用wcstombs()的所有字符串在每個C++函數的開始轉換,但我寧願不修改的lib到這樣的程度...

是否有固定的方式C#和C之間的編組與.NET Compact Framework一起工作?

+0

[Social.msdn](http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/4aed0776-638a-4fde-ad61-e2462b39a961)表示沒有:( – GSerg 2010-10-19 22:45:09

回答

6

不,沒有。

Microsoft documentation規定:

[...] .NET Framework精簡 僅支持Unicode,因此僅包括 CharSet.Unicode(和CharSet.Auto ,其等於Unicode)的值,並且 不支持 聲明語句的任何條款。這意味着 ExactSpelling屬性也不支持 。

其結果是,如果你的DLL功能 期望ANSI字符串,你需要 在DLL進行轉換, 或使用的重載的GetBytes方法 的字符串轉換爲字節數組 ASCIIEncoding類,之前調用該函數 ,因爲.NET Framework將始終將 指針傳遞給Unicode字符串。 [...]

解決方法是:在DLL

int MARSHALMOBILEDLL_API testString(const char* value); 
const char* MARSHALMOBILEDLL_API testReturnString(const char* value); 

函數包裝

[DllImport("marshalMobileDll.dll")] 
public static extern int testString(byte[] value); 

[DllImport("marshalMobileDll.dll")] 
public static extern System.IntPtr testReturnString(byte[] value); 

長途區號

string s1 = "1234567"; 
int v = Wrapper.testString(Encoding.ASCII.GetBytes(s1)); 

string s2 = "abcdef"; 
IntPtr ps3 = Wrapper.testReturnString(Encoding.ASCII.GetBytes(s2)); 
string s3 = IntPtrToString(ps3); 


private string IntPtrToString(IntPtr intPtr) 
{ 
    string retVal = ""; 

    byte b = 0; 
    int i = 0; 
    while ((b = Marshal.ReadByte(intPtr, i++)) != 0) 
    { 
    retVal += Convert.ToChar(b); 
    } 
    return retVal; 
} 
+0

終於!明確的轉換似乎是唯一可能的解決方案......非常感謝,現在它工作得非常好! – matpop 2016-03-09 09:49:09

2

Windows CE嚴重偏向於Unicode(大多數Win32 API甚至沒有ANSI等效)。因此,CF實際上並不適合ANSI,它需要一點「幫助」才能正確實現。

你可以告訴你要傳遞的數據爲單字節的編組程序,通過使用MarshalAs特性(the MSDN docs清楚地表明它是在CF的支持)的東西沿着這些線路空值終止值:

[DllImport("mydll.dll", SetLastError = true)] 
public static extern void Foo([MarshalAs(UnmanagedType.LPStr)]string myString); 
+0

不幸的是, MarshalAs在Compact Framework – tato 2010-10-20 16:15:54

+0

不支持根據誰? *大多數當然*是*支持。我經常使用它,除了CF工作外,我幾乎沒有做任何事情。 – ctacke 2010-10-20 16:53:38

+0

MSDN表示支持自3.5 SP1以來 – 2010-10-22 08:26:04

相關問題