PInvoke Marshalling Struct и BYTE * в качестве параметра результат плохой указатель - PullRequest
0 голосов
/ 12 октября 2011

Я потратил 1 день, чтобы выяснить, почему возникла эта проблема, но результат все равно не удался. Когда я отлаживаю в Native DLL, он показывает Bad Pointer для второго параметра. Здесь нужен эксперт, чтобы посоветовать, чего не хватает в моем шаге, который приводит к этой ошибке.

  • Native 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")] public static extern 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);
    }
  • Ошибка найдена в Native C ++

enter image description here

1 Ответ

0 голосов
/ 12 октября 2011

атрибут SizeParamIndex означает, что n-й параметр функции (начиная с нуля, считая слева) содержит фактический размер массива.ваша функция имеет только 2 параметра, а не 127.

Более того, вы поменяли местами параметры pbTranxData и CSTSaleInfo в C ++ и C #.

, вы можете использовать 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 *, вы можете изменить его на UnmanagedType.ByValTStr с заданным SizeConst.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...