We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

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

winfred_lu
winfred_lu asked
on
Medium Priority
720 Views
Last Modified: 2008-01-09
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))
    Next
    MsgBox(str)   'hex dump for the data
    Marshal.FreeHGlobal(buf)
  End If


I always got a System.AccessViolationException running my vb program.
How should I correct it?
Comment
Watch Question

Commented:
ByRef data As IntPtr

Replace with ByVal.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
dear AlexFM,
I replaced ByRef with ByVal but I got the same Exception.

Author

Commented:
Oh, I'm sorry.
It works now.
Thanks a lot. :)

Author

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
      Next
      Label1.Text += vbCrLf + str
    End If
  Next
  Marshal.FreeHGlobal(buf)

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?

Commented:
VB code is OK, but C++ code doesn't release buf buffer.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.