C ++ dll в VB.NET - структура совместимости - PullRequest
0 голосов
/ 12 февраля 2019

Я использую C ++ DLL в проекте VB.NET.
Я успешно вызываю некоторую функцию DLL, но если я вызываю функцию, которая возвращает указатель на структуру C ++, я получаю эту ошибку:

Попытка чтения или записи в защищенную память.Это часто указывает на то, что другая память повреждена.

Может быть, я не создаю правильную структуру в VB, не могли бы вы мне помочь?

Вот как я объявляю и вызываюфункция в VB:

<System.Runtime.InteropServices.DllImport("MobilePosAdapterCLib.dll", CallingConvention:=CallingConvention.Cdecl, SetLastError:=False)> 
Public Shared Function MobilePosAdapter_getLastTransactionResult() As System.IntPtr 
End Function
Dim risultato As System.IntPtr
Dim risultato2 As PaymentResult
risultato = MobilePosAdapter_getLastTransactionResult()
risultato2 = Marshal.PtrToStructure(risultato, GetType(PaymentResult)) ' error here

Это структура c ++:

typedef struct {
    char text[48 + 1];
    int attribute;
} ReceiptRow;

typedef struct {
    int numReceiptRows;
    int signatureRequired;
    ReceiptRow rows[200];
} Receipt;

typedef struct {
    int operationType;
    char posId[32 + 1];
    char terminalId[8 + 1];
    char transactionId[10 + 1];
    int transactionResult;
    char transactionDate[8 + 1];
    char transactionTime[9 + 1];
    char stan[6 + 1];
    int isReceiptPresent;
Receipt receipt;
} TransactionResult;

typedef struct {
    TransactionResult base;
    int amount;
    char pan[19 + 1];
    int cardType;
    int technologyType;
    char acquirerId[11 + 1];
    char acquirerName[16 + 1];
    char approvalCode[6 + 1];
    char merchantId[15 + 1];
    char actionCode[3 + 1];
    char posMessage[16 + 1];
    char emvApplicationId[32 + 1];
} PaymentResult;

А это моя структура VB.NET:

Public Structure ReceiptRow

    Public text As Char()
    ' tried also so:
    '<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=48)>
    'Public text As String

    Public attribute As Integer
End Structure

Public Structure Receipt
    Public numReceiptRows As Integer
    Public signatureRequired As Integer
    Public Shared rows() As ReceiptRow = Arrays.InitializeWithDefaultInstances(Of ReceiptRow)(200)
End Structure

Public Structure TransactionResult
    Public operationType As Integer
    Public posId As Char()
    Public terminalId As Char()
    Public transactionId As Char()
    Public transactionResult As Integer
    Public transactionDate As Char()
    Public transactionTime As Char()
    Public stan As Char()
    Public isReceiptPresent As Integer
    Public receipt As Receipt
End Structure

Public Structure PaymentResult
    Public base As TransactionResult
    Public amount As Integer
    Public pan As Char()
    Public cardType As Integer
    Public technologyType As Integer
    Public acquirerId As Char()
    Public acquirerName As Char()
    Public approvalCode As Char()
    Public merchantId As Char()
    Public actionCode As Char()
    Public posMessage As Char()
    Public emvApplicationId As Char()
End Structure

ОБНОВЛЕНИЕ:

Благодаря комментарию GSerg мне удалось получить почти все, моя последняя проблема - преобразование в VB.NET этой части:

typedef struct {
    int numReceiptRows;
    int signatureRequired;
    ReceiptRow rows[200];
} Receipt;

Кажется, работает с:

Public Structure Receipt
    Public numReceiptRows As Integer
    Public signatureRequired As Integer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)>
    Public rows As ReceiptRow()
End Structure
...