我有一个P / Invoke,其中一个C结构指针传递到Windows CE平台下的一个函数
C++ Code
typedef struct{
unsigned char MerchName[256];
unsigned char MerchCateCode[2];
unsigned char MerchId[15];
unsigned char TermId[8];
unsigned char TerminalType;
unsigned char Capability[3];
unsigned char ExCapability[5];
unsigned char TransCurrExp;
unsigned char ReferCurrExp;
unsigned char ReferCurrCode[2];
unsigned char CountryCode[2];
unsigned char TransCurrCode[2];
unsigned long ReferCurrCon;
unsigned char TransType;
unsigned char ForceOnline;
unsigned char GetDataPIN;
unsigned char SurportPSESel;
}EMV_PARAM;
SKY_EMV_API void SKY_EmvLib_SetParam(EMV_PARAM *tParam)
C#代码:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct EMV_PARAM
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string MerchName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string MerchCateCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string MerchId;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string TermId;
public byte TerminalType;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
public string Capability;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 5)]
public string ExCapability;
public byte TransCurrExp;
public byte ReferCurrExp;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string ReferCurrCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string CountryCode;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 2)]
public string TransCurrCode;
public int ReferCurrCon;
public byte TransType;
public byte ForceOnline;
public byte GetDataPIN;
public byte SurportPSESel;
}
[DllImport("SKY_EMV.dll")]
private static extern int SKY_EmvLib_SetParam(ref EMV_PARAM param);
问题是数据没有打包。我知道在C#代码中,字符串被视为Unicode字符串,当它进入C ++代码时,C#字符串中的每个字符将占用C ++端的2个字节。
例如我在C#中将MerchName设置为“abc”,它将在C ++端变为“a0b0c0”。由于该平台是Windows CE,因此该平台中没有CharSet.ASCII。
任何人都可以帮助如何在不改变C ++ EMV_Param结构的情况下解决这个问题,无论如何要改变C#代码才能使它工作?
答案 0 :(得分:1)
CharSet.Ansi
。这意味着您无法在C#struct定义中使用string
。相反,如果保持C ++不变,则必须使用字节数组。您面临的下一个问题是需要从UTF-16转换为ANSI / ASCII。如果您在C#端的文本限制为ASCII字符,那么这很容易做到。您只需将每个字符转换为其序数,并截断到0..127范围内。
这似乎很痛苦。坦率地说,正确的解决方案是修改C ++以接受UTF-16文本。如果底层库是ASCII,那么您可以在C ++代码中进行转换,该代码至少包含用于此目的的函数。