locked
Accessing a C++ Array in VB.Net RRS feed

  • Question

  • Hi,

    I am using a C++ dll provided by our Vendor.The function of this C++ is to return a pointer to an image array of size 640*480.I am calling this dll in a VB.Net project. I have done it using <DllImport > and  the function is also returning the address of the Array.Then I use marshal.copy to copy the values from the memory location to a local array.When I run this code I have a System Access Violation Exception.I found the cause. It seems like the VB is not able to properly read from the address and is throwing garbage  values into the array leading to this problem. I cant access the dll as it is proprietary. So is there any ways by which I can access the values from the physical address returned by the C++ dll in Vb.net?I have searched for solution in the web, but to use.Any help in this matter would be great

    Thank You.

    Monday, April 2, 2012 1:50 PM

All replies

  • Please post

    • the C++ declaration of the function
    • the VB declaration of the function
    • The code how you handle the data

    Armin

    Monday, April 2, 2012 2:48 PM
  •  The C++ declaration done by vendor:

    #ifdef _BUILD_INTERFACE_DLL_
      #define DLL_FUNCTION __declspec(dllexport)
    #else
      #define DLL_FUNCTION __declspec(dllimport)
    #endif
    
    extern "C"
    {
      DLL_FUNCTION unsigned short* GetThermoImageData(void);
    }
    
    

    VB Declaration:

    <DllImport ("PyroCam.dll",CallingConvention:=CallingConvention.Cdecl,EntryPoint:="_GetThermoImageData")> _
    Public Function GetThermoImageData() As IntPtr
    End Function

    Dll handling in code:

    Dim ptr as Intptr
    Dim length as integer = 640*480
    Dim imgarr(length) as bytes
    ptr = GetThermoImage()
    Marshal.Copy(ptr,imgarr,0,length)
    
    
    
    

    this throws an Access Violation Exception.

    Tuesday, April 3, 2012 12:09 PM
  • Try this:

    Dim imgarr(length - 1) as byte

    The upper bound is specified. As it's zero based, length = upper bound +1, or upper bound = length -1 

    I guess you're sure 640x480 bytes are provided.

    The types (Byte vs unsignged short (=UShort=UInt16)) don't match, but that's ok as long as buffer length matches.


    Armin



    Tuesday, April 3, 2012 12:19 PM
  • I tried  that but no use...

     The problem is not the exception part, the problem is that junk values are getting stored in the array and this corrupts the memory...leading to access violation..I want to know how to make Vb read the correct values from the address returned by the C++ dll.

    Tuesday, April 3, 2012 12:31 PM
  • I don't understand this description of the problem. Junk values don't lead to an exception, and if the exception is not the problem...?

    At which line exactly do you get the exception?

    Have you verified the return value of the function? Maybe it's NULL (intptr.zero)?

    The code looks good. For testing purpose, try this:

      Marshal.Copy(ptr,imgarr,0, 1)

    Does it succeed?

    What about the different data types (short vs byte)?


    Armin


    • Edited by Armin Zingler Tuesday, April 3, 2012 2:16 PM typo (no -> not)
    Tuesday, April 3, 2012 1:28 PM
  • ok let me explain it to you:

    1. the function returns a value, no null values.

    2.Marshal.Copy(ptr,imgarr,0,1) or for that matter Marshal.Copy(ptr,imgarr,0,1000) works but Marshal.Copy(ptr,imgarr,0,(length+1or- 1))does not work .It throws the access violation exception.The manual of the vendor says that the the function returns a pointer to a 1D array, but they don give the exact value of the array length.I assume it to be 640*480 because its the size of the image whose values the array points to.

    3.I think the values that get copied from ptr are imgarr are not the correct values.

    I hope that explains  my problem.

    Tuesday, April 3, 2012 1:51 PM
    • "the function returns a value, no null values."

    My question was if you have verified this. But taken from the rest of the reply, it doesn't seem to return NULL.

    • "Marshal.Copy(ptr,imgarr,0,1) or for that matter Marshal.Copy(ptr,imgarr,0,1000) works but Marshal.Copy(ptr,imgarr,0,(length+1or-1))does not work .It throws the access violation exception"

    That's important information. Obviously the function returns less values than you expect it to return. That's not a VB or Framework problem. You expect 640x480=307,200 bytes. What's the largest value for length that does not cause an exception? Try a manually coded binary search to find it quickly (try 100,000 first, then either 50,000 or 200,000 depending on the result of the previous test, and so on).

    • "I think the values that get copied from ptr are imgarr are not the correct values."

    As long as you're getting an exception you won't know.

    Again you didn't answer the question about the not matching types.


    Armin

    Tuesday, April 3, 2012 2:24 PM
  • Hi.

    I suppose you deal with LiveView option on camera or something of that kind.

    If it's so, I've found somehow that length should be 

    Dim length as integer = 640*480*3 - 128

    i.e. 921600 - 128 while the pointer should be something like ptr + 128 (I don't know how it can be made in vb.net, at least vb.net 2008). 128 - is the length of header file which can be generated separately. 

    But even if you leave 

    Dim length as integer = 640*480*3

    it's already possible to save image correctly to filestream and then to disk (but not to memorystream) though in Explorer it appears without thumbnail.

    Hope this can help to somebody.

    Serge


    • Edited by sergek26 Sunday, December 2, 2012 4:26 PM
    Sunday, December 2, 2012 4:14 PM