2015-08-24 43 views
0
[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. 的非托管函数当呼叫到达该函数内,我没有得到的字符串值“约翰”,“英国”,“约翰”和“美国”。元帅结构,其中包含串 - 在非托管C功能

[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); 
+1

这是一个互操作的问题。它需要完整看到整个互操作界面。你只显示了一半。你可以看到非托管界面,我们不能。 –

+0

@David Heffernan,我已更新。希望这有助于 – SHRI

+0

完美工作!谢谢Allot @David Heffernan – SHRI

回答

1

你的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; 
}