1

I'm using a C++ DLL in a VB.NET project.
I call some DLL function with success, but if I call a function that returns a C++ structure pointer I am getting this error:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Maybe I'm not creating the right structure in VB, could you help me?

This is how I declare and call the function in 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

This is the c++ struct:

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;

And this is my VB.NET structure:

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

UPDATE:

Thanks to GSerg's comment I managed to get almost everything, my last problem is converting to VB.NET this part:

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

It seems to work with:

Public Structure Receipt
    Public numReceiptRows As Integer
    Public signatureRequired As Integer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)>
    Public rows As ReceiptRow()
End Structure
Andrea
  • 148
  • 1
  • 9
  • 1
    https://stackoverflow.com/a/24539071/11683 – GSerg Feb 12 '19 at 12:35
  • @GSerg Thanks for reply, is it correct for "char text[48 + 1];"? Public text As Char() – Andrea Feb 12 '19 at 12:44
  • 1
    There's way too much code here. Classic mistake to try to debug the complex before you fully understand the simple. Cut it back to basics and take it from there. Don't be surprised if you need to use an out parameter rather than a return value for the structure. – David Heffernan Feb 12 '19 at 14:22
  • Thanks for reply, I can't simplify the DLL it's not made by me(I dont know C++, so I can't make another one). I call DLL simple functions with success, I've the problem only with complex result functions. – Andrea Feb 12 '19 at 14:43
  • Try the answers from [this link](https://stackoverflow.com/questions/4074585/attempted-to-read-or-write-protected-memory-this-is-often-an-indication-that-ot) – preciousbetine Feb 12 '19 at 16:23
  • @Andea Time to do some learning then. It is unrealistic to expect to solve problems on topics where you have no knowledge. – David Heffernan Feb 13 '19 at 07:21
  • @David Heffernan: you are right, but this is a weird situation. Normally I do all my stuff in VB.NET and C# (no one develops in C++ where i work, small company), but this time I have this third party C++ DLL and it's a pain.. I think that converting the C++ struct will solve the problem, could you do that please? – Andrea Feb 13 '19 at 09:48
  • Yes, I know how to convert this struct. But that's not what we are here for. Do you want to learn, or do you want somebody else who has the knowledge, to do a piece of work for you? – David Heffernan Feb 13 '19 at 09:52
  • Usually the first you said, this time the second. I dig as much as possible in the problems I meet, but this time I think it requires too much time to learn how to correctly "cast" a C++ structured pointer into a VB.NET object – Andrea Feb 13 '19 at 10:17
  • I understand. If you don't have time to learn how to do this yourself, you will need to find somebody who already has the knowledge, and pay them. Good luck! – David Heffernan Feb 13 '19 at 10:38
  • I updated the post – Andrea Feb 13 '19 at 13:07
  • Great question here. One of the commenters is harassing the OP - looks like he's simply withholding knowledge and waiting for payment. – Todd Main Jul 22 '20 at 04:30

0 Answers0