AccessViolationException while passing a byte array from VC++ .NET dll to VB.NET

I tried using VC++.Net to warp a old.dll (written in vc6) into new.dll, and new.dll would be used by VB.Net.

There was a function in my new.dll like:
int _stdcall abc_new(char * data)
  u_char * buf;
  int res;
  res = abc_old((u_char **)&buf);
  /* abc_old is a call to old.dll; it will alloc buf and fill it with data */
  if (res == 0) {
    memcpy(data, buf, 10);
    /* assume my buf will be always larger than 10 */
    return 0;
  return -1;

In my vb.Net, I declared:
  Public Declare Function abc_new Lib "new.dll" (ByRef data As IntPtr) As Integer
and used as:
  Dim rc As Integer
  Dim buf As IntPtr
  Dim str As String = ""

  buf = Marshal.AllocHGlobal(10)
  rc = abc_new(buf)
  If (rc = 0) Then
    Dim b(10) As Byte
    Dim i As Integer

    Marshal.Copy(buf, b, 0, 10)
    For i = 0 To 10
      str += ":" + Hex(b(i))
    MsgBox(str)   'hex dump for the data
  End If

I always got a System.AccessViolationException running my vb program.
How should I correct it?
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ByRef data As IntPtr

Replace with ByVal.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
winfred_luAuthor Commented:
dear AlexFM,
I replaced ByRef with ByVal but I got the same Exception.
winfred_luAuthor Commented:
Oh, I'm sorry.
It works now.
Thanks a lot. :)
winfred_luAuthor Commented:
If I put the calling abc_new codes in a loop.
Actually, I need to put them in a infinite loop and stop whenever clicking a button.
I tried to loop them for 500 times for testing first.

  Dim buf As IntPtr
  Dim b(1500) As Byte

  buf = Marshal.AllocHGlobal(1500)
  For i = 1 to 500
    rc = abc_new(buf)
    If (rc = 0) Then
      Dim j As Integer
      Dim str As String = ""
      Marshal.Copy(buf, b, 0, 100)
      For j = 0 To 100
        str += ":" + Hex(b(i))  'hexdump of data
      Label1.Text += vbCrLf + str
    End If

When the number of loop is small such as 10, 50 or 100, it runs fine.
If the number is big like 500, my program will hang there without response.

Was it due to too many times of memcpy in the dll?
If yes,
Is there any method to make performance better?
Some way I don't have to memcpy in dll and Marshal.Copy in vb.Net again?
VB code is OK, but C++ code doesn't release buf buffer.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual C++.NET

From novice to tech pro — start learning today.