2011-10-12 84 views
0

我花了1天的时间来找出这个问题发生的原因,但结果仍然失败。 当我在本机DLL中调试时,它显示第二个参数的错误指针。需要这里的专家来建议在我的步骤中缺少产生此错误的内容。PInvoke编组结构和BYTE *作为参数导致坏指针

  • 母语STRUCT
typedef struct 
     { 
      BYTE bcdTicketMainType; 
      BYTE bcdTicketSubType; 
      BYTE bcdValidityStartDate[4];  // YYYYMMDD 
      BYTE bcdValidityEndDate[4];  // YYYYMMDD 
      BYTE bcdPhysicalExpiryDate[4];  // YYYYMMDD 
      BYTE bFareZone; 
      SHORT sDepositAmount;    // NEW ARGUMENT 
      LONG lBalance;      // NEW ARGUMENT 
      BYTE bcdStationIDOrigin[2]; 
      BYTE bcdStationIDDestination[2]; 
      BYTE bcdPaymentType; 
      CHAR strPaymentMediaID[20]; 
      CHAR strAgentID[8]; 
      BYTE bcdShiftID; 
     } T_TK_KTMB_CSC_SALE_INFO; 
  • 结构在C#
public struct T_TK_KTMB_CSC_SALE_INFO 
    { 
     public byte bcdTicketMainType; // 1 
     public byte bcdTicketSubType; // 1 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)] 
     public byte[] bcdValidityStartDate;  // YYYYMMDD 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)] 
     public byte[] bcdValidityEndDate;  // YYYYMMDD 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4)] 
     public byte[] bcdPhysicalExpiryDate;  // YYYYMMDD 
     public byte bFareZone; 
     public short sDepositAmount;    // NEW ARGUMENT 
     public long lBalance;      // NEW ARGUMENT 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)] 
     public byte[] bcdStationIDOrigin; 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 2)] 
     public byte[] bcdStationIDDestination; 
     public byte bcdPaymentType; 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 20)] 
     public char[] szPaymentMediaID; 
     [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 8)] 
     public char[] szAgentID; 
     public byte bcdShiftID; 
    } 
  • 固有函数

INT KTMBBiz_CSCSale(T_TK_KTMB_CSC_SALE_INFO CSCSaleInfo,BYTE * pbTranxData);

  • 在C#

    [的DllImport( “KTMBBizRule.dll”)] 公共静态外部INT KTMBBiz_CSTSale([IN,OUT的MarshalAs(UnmanagedType.LPArray,SizeParamIndex => 127功能)] byte [] pbTranxData,T_TK_KTMB_CST_SALE_INFO CSTSaleInfo);称为在C#

  • 功能

private void btnCscSale_Click(object sender, EventArgs e) 
    { 
     T_TK_KTMB_CSC_SALE_INFO cscSale = new T_TK_KTMB_CSC_SALE_INFO(); 
     byte[] trxData = new byte[2]; 
     BizRule.KTMBBiz_CSCSale(cscSale, trxData); 
    } 
  • 错误创建于本机C++

enter image description here

+0

您的C#函数声明有两个参数交换。 –

回答

0

SizeParamIndex属性表示第n个函数参数(从零开始,从左数起)包含数组的实际大小。 您的函数只有2个参数,而不是127.

更重要的是,您在C++和C#中交换了pbTranxDataCSTSaleInfo参数。

可以使用SizeParamIndex让C++函数知道pbTranxData数组的大小:

C++

int KTMBBiz_CSCSale(T_TK_KTMB_CSC_SALE_INFO CSCSaleInfo, 
        BYTE* pbTranxData, INT iLength); 

C#

[DllImport("KTMBBizRule.dll")] 
public static extern int KTMBBiz_CSTSale(
     T_TK_KTMB_CST_SALE_INFO CSTSaleInfo, 
     [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=2)] 
     byte[] pbTranxData, 
     int iLength); 

现在KTMBBiz_CSTSale(cscSale, trxData, trxData.Length);

叫什么你还应该加[StructLayout(LayoutKind.Sequential)]之前你的C#结构。

而不是public char[] szPaymentMediaID;你可以说string szPaymentMediaID。 默认情况下,字符串编组为char *,您可以使用给定的SizeConst将其更改为UnmanagedType.ByValTStr