Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Windows Mobile中将C#字符串传递给非托管C DLL 我有一个非托管C++ DLL,我需要从一个强> Windows Mobile C应用程序< /St>>_C#_C++_Windows Mobile_Compact Framework_Interop - Fatal编程技术网

在Windows Mobile中将C#字符串传递给非托管C DLL 我有一个非托管C++ DLL,我需要从一个强> Windows Mobile C应用程序< /St>>

在Windows Mobile中将C#字符串传递给非托管C DLL 我有一个非托管C++ DLL,我需要从一个强> Windows Mobile C应用程序< /St>>,c#,c++,windows-mobile,compact-framework,interop,C#,C++,Windows Mobile,Compact Framework,Interop,我有C#包装器,它在桌面上运行得很好。我可以从C#桌面程序调用DLL函数,并毫无问题地传递字符串 然而,当我为移动平台编译lib和包装器时,我在DllImport行中得到一个错误,表示CharSet.ANSI无法识别。我唯一可以写的选项是CharSet.Auto和CharSet.Unicode 问题是,不管这个设置如何,在C++函数中接收的字符串都是宽字符字符串,而不是普通字符字符串,这是他们所期望的。 我们可以使用WCSTOBSF()来翻译每个C++函数开头的所有字符串,但是我不希望修改LIB

我有C#包装器,它在桌面上运行得很好。我可以从C#桌面程序调用DLL函数,并毫无问题地传递字符串

然而,当我为移动平台编译lib和包装器时,我在DllImport行中得到一个错误,表示CharSet.ANSI无法识别。我唯一可以写的选项是CharSet.Auto和CharSet.Unicode

问题是,不管这个设置如何,在C++函数中接收的字符串都是宽字符字符串,而不是普通字符字符串,这是他们所期望的。

我们可以使用WCSTOBSF()来翻译每个C++函数开头的所有字符串,但是我不希望修改LIB到这样的范围…


有没有一种方法可以修复C#和C之间与.NET Compact Framework一起工作的编组问题?

Windows CE严重偏向于Unicode(大多数Win32 API甚至没有ANSI等价物)。因此,CF也不能很好地与ANSI配合使用,它需要一些“帮助”来正确使用它

您可以通过使用MarshalAs属性(清楚地表明它在CF中受支持)告诉封送处理程序,您希望以单字节、以null结尾的值的形式传递数据,具体如下:

[DllImport("mydll.dll", SetLastError = true)]
public static extern void Foo([MarshalAs(UnmanagedType.LPStr)]string myString);
我觉得这很有用,即使你觉得它有点像马车

没有

指定:

[…].NET Compact Framework 仅支持Unicode,因此仅包括 Unicode(和CharSet.Auto 它等于Unicode)值,并且 不支持本协议的任何条款 声明声明声明。这意味着 ExactSpelling属性也不可用 支持

因此,如果您的DLL函数 需要ANSI字符串,您需要 要在DLL中执行转换, 或者将字符串转换为字节数组 使用重载的GetBytes方法 在之前 调用函数,因为.NET 紧凑的框架将始终通过 指向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;
}

说不:(不幸的是,根据谁的说法,Compact Framework不支持Marshallas?Marshallas肯定是受支持的。我经常使用它,除了CF work之外几乎什么都不做。MSDN表示从3.5 SP1开始支持。很抱歉,我之前的模糊评论。Marshallas肯定是受支持的。但您建议的调用在运行时失败,并没有提示。)portedException,由于使用了LPStr类型。Microsoft documentation()指定了这一点(在本页中始终搜索所有Unicode)。最后!显式转换似乎是唯一可能的解决方案…非常感谢,它现在工作得非常好!