从本机C++;DLL到C#应用程序 我在C++中编写了一个DLL。其中一个函数写入字符数组

从本机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:

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:
    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();