Reputation: 2466
[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);
}
In the above code, NativeMethods.GenerateCert is an unmanaged function of C. When Call reaches inside of this function, I am not getting the string values "John", "UK", "Johann" and "US".
[DllImport("AuthLibrary.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GenerateCert(ref sCertData_d cert);
Unmanaged function prototype is like this -
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);
Upvotes: 0
Views: 170
Reputation: 613572
Your translation of sName_d
is wrong. The unmanaged structure is:
typedef struct sName_d
{
char szCountry[0x35];
char szCommonName[0x35];
} sName_d;
These are inline character arrays. You marshaled these as UnmanagedType.LPStr
. That's a pointer to null-terminated string. You need to use UnmanagedType.ByValTStr
.
Used for in-line, fixed-length character arrays that appear within a structure. The character type used with ByValTStr is determined by the System.Runtime.InteropServices.CharSet argument of the System.Runtime.InteropServices.StructLayoutAttribute attribute applied to the containing structure. Always use the MarshalAsAttribute.SizeConst field to indicate the size of the array. .NET Framework ByValTStr types behave like C-style, fixed-size strings inside a structure (for example,
char s[5]
).
Your translation should be:
[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;
}
Upvotes: 1