title: C++ dll in VB.NET - Structure compatibility
body: <p>I'm using a C++ DLL in a VB.NET project.<br>
  I call some DLL function with success, but if I call a function that returns a C++ structure pointer I am getting this error:</p>
  
  <blockquote>
    <p>Attempted to read or write protected memory. This is often an indication that other memory is corrupt.</p>
  </blockquote>
  
  <p>Maybe I'm not creating the right structure in VB, could you help me?</p>
  
  <p>This is how I declare and call the function in VB:</p>
  
  <pre class="lang-vb prettyprint-override"><code>&lt;System.Runtime.InteropServices.DllImport("MobilePosAdapterCLib.dll", CallingConvention:=CallingConvention.Cdecl, SetLastError:=False)&gt; 
  Public Shared Function MobilePosAdapter_getLastTransactionResult() As System.IntPtr 
  End Function
  </code></pre>
  
  <pre class="lang-vb prettyprint-override"><code>Dim risultato As System.IntPtr
  Dim risultato2 As PaymentResult
  risultato = MobilePosAdapter_getLastTransactionResult()
  risultato2 = Marshal.PtrToStructure(risultato, GetType(PaymentResult)) ' error here
  </code></pre>
  
  <p>This is the c++ struct:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>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;
  </code></pre>
  
  <p>And this is my VB.NET structure:</p>
  
  <pre class="lang-vb prettyprint-override"><code>Public Structure ReceiptRow
  
      Public text As Char()
      ' tried also so:
      '&lt;MarshalAs(UnmanagedType.ByValTStr, SizeConst:=48)&gt;
      '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
  </code></pre>
  
  <p>UPDATE:</p>
  
  <p>Thanks to GSerg's comment I managed to get almost everything, my last problem is converting to VB.NET this part:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>typedef struct {
      int numReceiptRows;
      int signatureRequired;
      ReceiptRow rows[200];
  } Receipt;
  </code></pre>
  
  <p>It seems to work with:</p>
  
  <pre class="lang-vb prettyprint-override"><code>Public Structure Receipt
      Public numReceiptRows As Integer
      Public signatureRequired As Integer
      &lt;MarshalAs(UnmanagedType.ByValArray, SizeConst:=200)&gt;
      Public rows As ReceiptRow()
  End Structure
  </code></pre>