在Windows CE平台下使用C / C ++ strut进行C#P / Invoke

时间:2014-01-14 20:55:37

标签: c# pinvoke windows-ce

我有一个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#代码才能使它工作?

1 个答案:

答案 0 :(得分:1)

CE上不存在

CharSet.Ansi。这意味着您无法在C#struct定义中使用string。相反,如果保持C ++不变,则必须使用字节数组。您面临的下一个问题是需要从UTF-16转换为ANSI / ASCII。如果您在C#端的文本限制为ASCII字符,那么这很容易做到。您只需将每个字符转换为其序数,并截断到0..127范围内。

这似乎很痛苦。坦率地说,正确的解决方案是修改C ++以接受UTF-16文本。如果底层库是ASCII,那么您可以在C ++代码中进行转换,该代码至少包含用于此目的的函数。