从本机C++;DLL到C#应用程序 我在C++中编写了一个DLL。其中一个函数写入字符数组
C++函数从本机C++;DLL到C#应用程序 我在C++中编写了一个DLL。其中一个函数写入字符数组,c#,c++,string,visual-studio-2008,dllimport,C#,C++,String,Visual Studio 2008,Dllimport,C++函数 EXPORT int xmain(int argc, char argv[], char argv2[]) { char pTypeName[4096]; ... //Other pTypeName ends up populated with "Portable Network Graphics" //This code verifies that pTypeName is populated with what I think it is:
EXPORT int xmain(int argc, char argv[], char argv2[])
{
char pTypeName[4096];
...
//Other pTypeName ends up populated with "Portable Network Graphics"
//This code verifies that pTypeName is populated with what I think it is:
char szBuff[64];
sprintf(szBuff, pTypeName, 0);
MessageBoxA(NULL, szBuff, szBuff, MB_OK);
//The caption and title are "Portable Network Graphics"
...
//Here, I attempt to copy the value in pTypeName to parameter 3.
sprintf(argv2, szBuff, 0);
return ret;
}
C#进口
C#函数
我曾试图通过引用传递参数,并使C++ DLL填充参数。尽管我已经验证了DLL中的值是正确的,但乱七八糟的信息会传递给C#应用程序
如何将正确的字符串值写入C#字符串?为DLLImport调用提供一些其他信息。请看我自己的以下示例:
[DllImport("tcpipNexIbnk.dll", EntryPoint = "SendData", CallingConvention = CallingConvention.Cdecl)]
public static extern int Send([MarshalAs(UnmanagedType.LPWStr)]string message);
请注意两件事,CallingConvention参数:
CallingConvention=CallingConvention.Cdecl)
照原样用吧
然后在C++字符串类型后面,可以使用MalSalas指令来使用不同的非托管类型,将C的字符串参数投射到C++程序中的本机字符串类型:
public static extern int Send([MarshalAs(UnmanagedType.LPWStr)]string message);
希望有帮助。使用
StringBuilder
传递本机代码可以填充的字符数组(请参阅)
声明函数:
[DllImport("FirstDll.dll", CharSet=CharSet.Ansi)]
public static extern int xmain(int argc, string argv, StringBuilder argv2);
使用它:
// allocate a StringBuilder with enough space; if it is too small,
// the native code will corrupt memory
StringBuilder sb = new StringBuilder(4096);
xmain(2, @"C:\hhh.bmp", sb);
string argv2 = sb.ToString();
尝试在C#项目中创建一个“不安全”空间。选择CallingConvention.Cdecl选项时,我必须确保我的DLL使用u declspec(dllexport)导出函数。对吗?使用Marshallas关键字本身并不能解决这个问题,但我想当我转向Unicode兼容时,我必须记住这一点。这个解决方案解决了我的问题。我希望我可以使用像char[]ch=new char[4096]这样的字符数组,但是失败了。知道为什么吗?IIRC,
char[]
始终被编组为16位字符数组(本机类型WCHAR
),并且不参与CharSet.ANSI
为string
/StringBuilder
执行的ANSI/Unicode转换。此外,我认为传递一个char[]
并不会自动传递指向数组中第一个元素的指针(C代码所期望的);要强制执行此操作,可以在DllImport
签名中将参数指定为ref char
,并在方法调用中使用ref ch[0]
调用它。
[DllImport("FirstDll.dll", CharSet=CharSet.Ansi)]
public static extern int xmain(int argc, string argv, StringBuilder argv2);
// allocate a StringBuilder with enough space; if it is too small,
// the native code will corrupt memory
StringBuilder sb = new StringBuilder(4096);
xmain(2, @"C:\hhh.bmp", sb);
string argv2 = sb.ToString();