LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How do I get an array from CVI to VB6?

I am trying to use a SAFEARRAY structure to pass data from CVI to VB6.0 by using the convert 1D array function. While the function will indeed pass its value, I am getting only zeros when I access the array in the calling VB program. Here is the small test program I wrote to keep things simple.


Labwindows/CVI, built a DLL using _stdcall and export tagged Items (I had to delete the leading bracket in the includes for this post);
#include cviauto.h>
#include formatio.h>
#include utility.h>
#include ansi_c.h>
#include userint.h>
int DLLEXPORT DLLSTDCALL dspReturnPixels (LPSAFEARRAY *Spel_mean)
{
int pel_mean[21504];
short int i;
for (i = 0; i < 21504; i++)
{
pel_mean[i] = i;
}
CA_Array1DToSafeArray (pel_mean, CAVT_INT, 21504, Spel_mean);
return (4);
}
In Visual Basic 6.0 I included a module with only this;
Declare Function dspReturnPixels& Lib "tstary_dbg.dll" (x1() As Long)

The VB calling program is this;
Private Sub cmdGetary_Click()
Dim tar(21504) As Long
Dim rerr As Long
rerr = 5
rerr = dspReturnPixels&(tar())
lblAryval.Caption = tar(Val(txtSubs.Text))
End Sub

No matter what I enter into txtSubs, the lblAryval displays 0. However rerr is set to 4 on return from dspReturnPixels.

I hope I just overlooked something simple.
Thanks,
Doug.
0 Kudos
Message 1 of 2
(3,363 Views)
When you use SAFEARRAY as a parameter, VB passes you an existing SAFEARRAY pointer. CA_Array1DToSafeArray creates a new safearray that VB does not know about, which is why you were not able to pass the data back. You can use the SafeArray functions that are part of the Windows SDK to copy our data to the SafeArray. Make sure to add oleaut32.lib to your CVI project.

int DLLEXPORT dspReturnPixels (SAFEARRAY **Spel_mean)
{
int pel_mean[21504];
short int i;
long lElements; // number of elements in the array
VARTYPE vt;
int* pdata;

for (i = 0; i < 21504; i++)
{
pel_mean[i] = i;
}

// checking if it is an one-dimensional array
if(SafeArrayGetDim(*Spel_mean) != 1)
return 1;

SafeArrayGetVartype(*Spel_mean,&vt);
if(vt != VT_I4) return 1;

// how many elements are there in the array
if( (*Spel_mean)->rgsabound[0].cElements != 21504) return 1;

// locking the array before using its elements
SafeArrayLock(*Spel_mean);
SafeArrayAccessData(*Spel_mean, (void HUGEP**)&pdata);

//copying the data
memcpy(pdata,pel_mean,21504*sizeof(int));

// releasing the array
SafeArrayUnlock(*Spel_mean);

return (4);
}


And you need to change your VB declaration to the following to reflect the return type.

Private Declare Function dspReturnPixels Lib "test.dll" (x1() As Long) As Long

Refer to the MSDN for more information about the safearray functions.

The following document provides you with some alternatives if you do not want to use SafeArrays. The pointer approach is the simplest.

http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q207931

Hope this helps
Bilal Durrani
NI
0 Kudos
Message 2 of 2
(3,346 Views)