Hi, I need help with SafeArray structure, in short I need to import Variant from Excel VBA using dll and change array by reference, I succeeded in bringing array in and working with it, but I do not know how to get back
here is my code:
c++ side:
short __stdcall Single_SafeArray(VARIANT *pv){
int i,j,k;
long lBound,uBound;
HRESULT lResult;
double** new_arr;
long m=0;
//Determine that Variant is an array by testing its type for the VT_ARRAY bit
if((pv->vt|VT_ARRAY)==0)
return (1);
//Determine the array type
VARTYPE vt_type;
if(!pv->parray) return (4);
lResult=SafeArrayGetVartype(pv->parray,&vt_type);
if(lResult!=S_OK) return (2);
//Determine the number of dimensions
int dims = SafeArrayGetDim(pv->parray);
if(dims<1 || dims>2) return(3);
//Get Upper and Lower Bound for each dimensions
int dim_size[MAX_SIZE];
for(i=1;i<=dims;i++){
if(SafeArrayGetLBound(pv->parray,i,&lBound)<0 ||
SafeArrayGetUBound(pv->parray,i,&uBound)<0)
return(4);
//dim_size[0]=rows and dim_size[1]=cols
dim_size[i-1]=uBound-lBound+1;
}
//convert to one dimensional array of doubles
double* arr;
lResult=SafeArrayAccessData(pv->parray,(void**)&arr);
if(lResult!=S_OK) return(5);
//since arr[0]=junk arr[1]=1-st element and so for...by the Way I do not know why?
//and since in VB arrays stored col by col
//initialize new array since my other fnc works with double arrays
new_arr=new double*[dim_size[0]];
for(i=0;i<dim_size[0];i++)
new_arr=new double[dim_size[1]];
for(i=0;i<dim_size[0];i++){
j=2*i+1;
for (k=0;k<dim_size[1];k++){
new_arr[k]=arr[j];
j+=2*dim_size[0];
}
}
//Work with Array
for(i=0;i<dim_size[0];i++){
for(j=0;j<dim_size[1];j++){
new_arr[j]=new_arr[j]+5;
}
}
//Unlock Array
lResult=SafeArrayUnaccessData(pv->parray);
if(lResult!=S_OK) return(5);
//now I need to get back to VB but I stuck , HOW, PLEASE HELP?
vba side:
Private Declare Function Single_SafeArray _
Lib "C:\MyStDll.dll" (ByRef arr As Variant) As Integer
Sub Try_OneDimensionSafeArray()
Dim arr As Variant, k As Integer
Dim arr_rows As Integer, arr_cols As Integer, j As Integer, i As Integer
'Initialize Size of Array
arr = ActiveSheet.Range("target_array").Value
k = Single_SafeArray(arr)
ActiveSheet.Range("return_array").Value = arr
End Sub
thanks
Ilya
here is my code:
c++ side:
short __stdcall Single_SafeArray(VARIANT *pv){
int i,j,k;
long lBound,uBound;
HRESULT lResult;
double** new_arr;
long m=0;
//Determine that Variant is an array by testing its type for the VT_ARRAY bit
if((pv->vt|VT_ARRAY)==0)
return (1);
//Determine the array type
VARTYPE vt_type;
if(!pv->parray) return (4);
lResult=SafeArrayGetVartype(pv->parray,&vt_type);
if(lResult!=S_OK) return (2);
//Determine the number of dimensions
int dims = SafeArrayGetDim(pv->parray);
if(dims<1 || dims>2) return(3);
//Get Upper and Lower Bound for each dimensions
int dim_size[MAX_SIZE];
for(i=1;i<=dims;i++){
if(SafeArrayGetLBound(pv->parray,i,&lBound)<0 ||
SafeArrayGetUBound(pv->parray,i,&uBound)<0)
return(4);
//dim_size[0]=rows and dim_size[1]=cols
dim_size[i-1]=uBound-lBound+1;
}
//convert to one dimensional array of doubles
double* arr;
lResult=SafeArrayAccessData(pv->parray,(void**)&arr);
if(lResult!=S_OK) return(5);
//since arr[0]=junk arr[1]=1-st element and so for...by the Way I do not know why?
//and since in VB arrays stored col by col
//initialize new array since my other fnc works with double arrays
new_arr=new double*[dim_size[0]];
for(i=0;i<dim_size[0];i++)
new_arr=new double[dim_size[1]];
for(i=0;i<dim_size[0];i++){
j=2*i+1;
for (k=0;k<dim_size[1];k++){
new_arr[k]=arr[j];
j+=2*dim_size[0];
}
}
//Work with Array
for(i=0;i<dim_size[0];i++){
for(j=0;j<dim_size[1];j++){
new_arr[j]=new_arr[j]+5;
}
}
//Unlock Array
lResult=SafeArrayUnaccessData(pv->parray);
if(lResult!=S_OK) return(5);
//now I need to get back to VB but I stuck , HOW, PLEASE HELP?
vba side:
Private Declare Function Single_SafeArray _
Lib "C:\MyStDll.dll" (ByRef arr As Variant) As Integer
Sub Try_OneDimensionSafeArray()
Dim arr As Variant, k As Integer
Dim arr_rows As Integer, arr_cols As Integer, j As Integer, i As Integer
'Initialize Size of Array
arr = ActiveSheet.Range("target_array").Value
k = Single_SafeArray(arr)
ActiveSheet.Range("return_array").Value = arr
End Sub
thanks
Ilya