2010-10-19 99 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

相关问题