[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);
}
在上面的代码中,NativeMethods.GenerateCert是C的非托管函数。 当Call到达此函数内部时,我没有得到字符串值" John"," UK"," Johann"和"美国"。
[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);
答案 0 :(得分:1)
sName_d
的翻译错误。非托管结构是:
typedef struct sName_d
{
char szCountry[0x35];
char szCommonName[0x35];
} sName_d;
这些是内联字符数组。您将这些编组为UnmanagedType.LPStr
。这是一个指向以null结尾的字符串的指针。您需要使用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;
}