包含字符串的封送结构-在非托管C函数中接收到错误的字符串

本文关键字:字符串 函数 错误 结构 包含 | 更新日期: 2023-09-27 18:09:35

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct sName_d
{
[MarshalAs(UnmanagedType.LPStr)]
public string szCountry;
[MarshalAs(UnmanagedType.LPStr)]
public string szCommonName;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct sCertData_d
{
public Int32 dwVersion;
public sName_d sIssuer;
public sName_d sSubject;
}
public void GenerateCert()
{
sCertData_d cert = new sCertData_d();
sName_d caIssuer = new sName_d();
caIssuer.szCountry = "US";
caIssuer.szCommonName = "John";
sName_d caSubject = new sName_d();
caSubject.szCountry = "UK";
caSubject.szCommonName = "Johann";
cert.sIssuer = caIssuer;
cert.sSubject= caSubject;
NativeMethods.GenerateCert(ref cert);
}

在上面的代码中,GenerateCert是C语言的一个非托管函数。当调用到达这个函数内部时,我没有得到字符串值"John","UK","Johann"answers"US"。

[DllImport("AuthLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GenerateCert(ref sCertData_d cert);

非托管函数原型如下-

typedef struct sName_d
{
char szCountry[0x35];
char szCommonName[0x35];
}sName_d;
typedef struct sCertData_d
{
int version;
sName_d sIssuer;
sName_d sSubject;
}sCertData_d;
int GenerateCert(const sCertData_d *psCert);

包含字符串的封送结构-在非托管C函数中接收到错误的字符串

您对sName_d的翻译错误。非托管结构为:

typedef struct sName_d
{
    char szCountry[0x35];
    char szCommonName[0x35];
} sName_d;

这些是内联字符数组。你将这些编组为UnmanagedType.LPStr。这是指向以空结束的字符串的指针。您需要使用UnmanagedType.ByValTStr

用于出现在结构内的内联固定长度字符数组。ByValTStr使用的字符类型由应用于包含结构的System.Runtime.InteropServices.StructLayoutAttribute属性的System.Runtime.InteropServices.CharSet参数决定。始终使用MarshalAsAttribute。SizeConst字段表示数组的大小。. net Framework ByValTStr类型的行为类似于c风格,固定大小的字符串内部的结构(例如,char s[5])。

你的翻译应该是:

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct sName_d
{
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x35)]
    public string szCountry;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x35)]
    public string szCommonName;
}