tat*_*ato 8 c# c++ interop compact-framework windows-mobile
我有一个非托管的c ++ DLL,我需要从Windows Mobile C#应用程序调用.
我有C#包装器,它在桌面上很好用.我可以从C#桌面程序调用DLL函数并传递字符串没有问题.
但是,当我编译lib和移动平台的包装器时,我在DllImport行中收到错误,指出CharSet.ANSI无法识别.我允许写的唯一选项是CharSet.Auto和CharSet.Unicode.
问题在于,无论此设置如何,在c ++函数中接收的字符串都是宽字符串,而不是它们所期望的普通char*字符串.
我们可以使用wcstombs()来翻译每个c ++函数开头的所有字符串,但我宁愿不修改lib到这样的程度......
有没有办法修复与.NET Compact Framework一起使用的C#和C之间的编组?
不,没有.
Microsoft文档指定:
[...] .NET Compact Framework 仅支持Unicode,因此仅包含CharSet.Unicode(和CharSet.Auto等于Unicode)值,并且不支持Declare语句的任何子句.这意味着也不支持ExactSpelling属性.
因此,如果您的DLL函数需要ANSI字符串,则需要在DLL中执行转换,或者在调用函数之前使用ASCIIEncoding类的重载GetBytes方法将字符串转换为字节数组,因为.NET Compact Framework将始终传递指向Unicode字符串的指针.[...]
解决方案是:
DLL中的函数
int MARSHALMOBILEDLL_API testString(const char* value);
const char* MARSHALMOBILEDLL_API testReturnString(const char* value);
Run Code Online (Sandbox Code Playgroud)
包装纸
[DllImport("marshalMobileDll.dll")]
public static extern int testString(byte[] value);
[DllImport("marshalMobileDll.dll")]
public static extern System.IntPtr testReturnString(byte[] value);
Run Code Online (Sandbox Code Playgroud)
致电代码
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3313 次 |
| 最近记录: |