Accessing a C++ Array in VB.Net
-
Monday, April 02, 2012 1:50 PM
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.
All Replies
-
Monday, April 02, 2012 2:48 PM
Please post
- the C++ declaration of the function
- the VB declaration of the function
- The code how you handle the data
Armin
-
Tuesday, April 03, 2012 12:09 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 03, 2012 12:19 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
- Edited by Armin Zingler Tuesday, April 03, 2012 12:20 PM
- Edited by Armin Zingler Tuesday, April 03, 2012 12:21 PM
-
Tuesday, April 03, 2012 12:31 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 03, 2012 1:28 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 03, 2012 2:16 PM typo (no -> not)
-
Tuesday, April 03, 2012 1:51 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 03, 2012 2:24 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
-
Sunday, December 02, 2012 4:14 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

