From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for VB6

cancel
Showing results for 
Search instead for 
Did you mean: 

In VB6, how do I pass the array returned by ImagetoArray() to a C++ function by reference not by value?

I have been puzzled by the problem for days, and your help is sincerely appreciated.

I use VB6 and a NI1430 board to grab images from a UNIQ1830-CL camera.  After the image is obtained, I use ImageToArray to get the data, and pass the array to a C++ function to do centroiding for a subregion of the image.  The C++ function resides in a custom-made dll named  'mathLib'.

 

The signature of the C++ function is:

STDMETHODIMP Cmath::centroid(VARIANT *image, int left, int width, int top, int height, VARIANT *theCentroid) ;

 

To call the C function from VB6, I do:

dim centroid as variant

dim imageData as variant

...

 

let imageData = CWIMAQImage.ImageToArray 

Let centroid = mathLib.centroid(imageData, regionLeft, regionWidth, regionTop, regionHeight)  

...

 

I tried the NI1430 and a board from another company.  The 'imageData' look the same in VB6 - both are 2D Integer arrays of size 1024x1024.  However when the array is passed to the C++ routine, there is a 5 times difference in processing speed.  I examined the array on the C++ side.  It turns out that the 'vt' field has different values.  For the array coming from NI1430, vt = 0x2002 (i.e. VT_ARRAY & VT_I2), which incates it's passed in by value.  While for the array coming from the other board, vt = 0x6002 (i.e. VT_BYREF & VT_ARRAY & VT_I2), which says it's passed by reference.  Since I call the C++ function for many sub regions in the image, and each call results in a new copy of the NI image array, the slowness in speed for the NI board is profound.

 

So my question is: In VB6, how do I get a reference to the array returned by ImagetoArray() ?  I've tried to obtain the address of the array, pass the first element of the array, etc.  none of them worked.  Please help.

 

0 Kudos
Message 1 of 6
(8,247 Views)

aoslo,

 

While VB doesn't necessarily have pointers, you can create a class that acts like a pointer by using the Win API functions to allocate and deallocate. There is a tutorial of this process here.

 

However, the better way to go about this may be to write a C++ wrapper for your C++ DLL to handle pointers (use pointer array data type). Let me know if this was the answer you were looking for and if you are able to pass your array by reference. If not, if you were to print your array after using the ImagetoArray() call, does this array look roughly how you would expect it to based on your image?

 

Best,

Jason M.
Applications Engineer
National Instruments
0 Kudos
Message 2 of 6
(8,223 Views)

Hello,

 

In fact, the C++ function expects the input to be a pointer to an array (please check the function signature in my post).  The data passed in from NI1430 is a copy of an array, and it really slows down the function.

 

My other frame grabber is from DataTranslation.  Their function to retrieve the pixel array from the image is: getImageData()   (compare to NI's ImageToArray()).  From what I can tell (the 'vt' value  in my post) their method returns an pointer to the array, while NI's returns a copy of the array. Hence the big difference in speed.

 

I compared the DT array and the NI array in VB6, they're the same - same dimensions and same data type.  I even exported the arrays to Matlab and plotted them, and the resulted images look the same.  

 

Someone on the internet speculated that the memory of NI1430 is read-only, so the ImageToArray() method can only return a copy of the image rather than hand out the pointer to the memory.  Could you confirm if this is the case?

 

 

0 Kudos
Message 3 of 6
(8,212 Views)

aoslo,

 

In response to the first question asked, this resource explains much clearer how to pass by reference in VB (In response to this question):

 

Sub PassArray()
Dim strString() As String
Dim n As Integer
DoSomethingWithArray strString
For n = LBound(strString) To UBound(strString)
Debug.Print n
Next
End Sub

Sub DoSomethingWithArray(ByRef strArray() As String)
Dim n As Integer
ReDim Preserve strArray(0 To 99)
Randomize
For n = 0 To 99
strArray(n) = CStr(n)
Next
End Sub

 

I'd have to do some digging to look into your most recent question. Let me know if the above code and resource allows you any utilization of your image.

 

Cheers,

Jason M.
Applications Engineer
National Instruments
0 Kudos
Message 4 of 6
(8,195 Views)

Sure I can do all those things to pass the array to another VB function by reference.  My problem is that the array is passed to a C++ function. Somehow C++ receives the NI array as a copy of the array, and the DT array as a reference to the array, although I use exactly the same lines of code for both boards.

 

In vb6:

    for NI:       imgData = cwimaqimage.ImageToArray()    

    for DT:      imgData = dtimageclass.getImageData()

 

then call the C++ function:

             centroid(imgData, left, top, width, height ...)

 

(The C++ function signature is: centroid(Variant* image, int left, int top, int width, int height ...) )

 

When I examine 'imgData' in the C++ function, NI is a copy, but DT is a reference.  I have to speculate that the difference is from how the NI CWIMAQ library maps the NI board memory.  

Thanks in advance for your insights.   

 

 

 

 

 

 

0 Kudos
Message 5 of 6
(8,187 Views)

Hi aoslo,

 

While we cannot guarantee that a third party's drivers and instruments will act the same as ours, we can help you develop an adequate work around in software in this case to give the same functionality. I believe that your conjecture is probably correct in that the two classes from two separate drivers act differently and involve different calls. You should be able to define your imgData as a reference array with the above work around. It is difficult to speculate on exactly what is occurring in the DT library and function call.

 

Cheers,

Jason M.
Applications Engineer
National Instruments
0 Kudos
Message 6 of 6
(8,155 Views)