How To pass 2D String array to VB from VC++ Using Safe array
Author |
Message |
Ravi Ravigula #1 / 4
|
 How To pass 2D String array to VB from VC++ Using Safe array
Hi every one I am trying to pass 2D array of string back to VB. Compile no problem but My Application crashes. I can Pass 1D String no problem Here is my sample code. Pls help me out Is there is any other way to do it. IDL: [id(6), helpstring("method ProcessStringArray")] HRESULT ProcessStringArray([out]SAFEARRAY (BSTR) *strOutputArray); Function Defintion: STDMETHODIMP CTestMacroInterface::ProcessStringArray( SAFEARRAY **ppOutputArray) { SAFEARRAYBOUND aDim[2]; aDim[0].lLbound = 0; aDim[0].cElements = 2; aDim[1].lLbound = 0; aDim[1].cElements = 3; *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); FillData((BSTR**)(*ppOutputArray)->pvData); Quote: }
void FillData(BSTR** ppMyData) { ppMyData[0][0] = SysAllocString(OLESTR("SOURCE_VA")); ppMyData[0][1] = SysAllocString(OLESTR("ACV")); ppMyData[0][2] = SysAllocString(OLESTR("10")); ppMyData[1][0] = SysAllocString(OLESTR("SOURCE_VB")); ppMyData[1][1] = SysAllocString(OLESTR("ACV")); ppMyData[1][2] = SysAllocString(OLESTR("20")); Quote: } }
|
Wed, 14 Jul 2004 02:57:31 GMT |
|
 |
Igor Tandetni #2 / 4
|
 How To pass 2D String array to VB from VC++ Using Safe array
First, you should not access pvData directly. You should use SafeArrayAccessData and SafeArrayUnaccessData. Second, your FillData function interprets the array as if it stores an array of BSTR* pointers, each of which points to an array of BSTRs. It is not so. Safearray holds one sequential chunk of BSTRs in column-major order, that is (0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2) in your case. Similar to multidimensional arrays in C and C++, only in C they are stored in row-major order. -- With best wishes, Igor Tandetnik "For every complex problem, there is a solution that is simple, neat, and wrong." H.L. Mencken
Quote: > Hi every one I am trying to pass 2D array of string back to VB. Compile no > problem but My Application crashes. > I can Pass 1D String no problem > Here is my sample code. Pls help me out Is there is any other way to do it. > IDL: > [id(6), helpstring("method ProcessStringArray")] HRESULT > ProcessStringArray([out]SAFEARRAY (BSTR) *strOutputArray); > Function Defintion: > STDMETHODIMP CTestMacroInterface::ProcessStringArray( SAFEARRAY > **ppOutputArray) > { > SAFEARRAYBOUND aDim[2]; > aDim[0].lLbound = 0; > aDim[0].cElements = 2; > aDim[1].lLbound = 0; > aDim[1].cElements = 3; > *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); > FillData((BSTR**)(*ppOutputArray)->pvData); > } > void FillData(BSTR** ppMyData) > { > ppMyData[0][0] = SysAllocString(OLESTR("SOURCE_VA")); > ppMyData[0][1] = SysAllocString(OLESTR("ACV")); > ppMyData[0][2] = SysAllocString(OLESTR("10")); > ppMyData[1][0] = SysAllocString(OLESTR("SOURCE_VB")); > ppMyData[1][1] = SysAllocString(OLESTR("ACV")); > ppMyData[1][2] = SysAllocString(OLESTR("20")); > }
|
Wed, 14 Jul 2004 03:18:12 GMT |
|
 |
Ravi Ravigula #3 / 4
|
 How To pass 2D String array to VB from VC++ Using Safe array
Thanks Igor I try the way You suggested. But I want to know How to add the data to the pointer array In My function I want ruturn 2 rows and 3 colums string array STDMETHODIMP TestMacroInterface::ProcessStringArray( SAFEARRAY**ppOutputArray) { HRESULT hresult; SAFEARRAYBOUND aDim[2] aDim[0].lLbound = 0; aDim[0].cElements = 3; aDim[1].lLbound = 0; aDim[1].cElements = 2 BSTR HUGEP *pbstr; *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); if (*ppOutputArray==NULL) { ::MessageBox(NULL, _T("NOT_OK"), _T("Pickup"), MB_OK); } else hresult=SafeArrayAccessData(*ppOutputArray,(void HUGEP**)&pbstr) Now How Do I add the data to my BSTR pointer will it work ??? pbstr[0][0] = SysAllocString(OLESTR("SOURCE_VA")); pbstr[0][1] = SysAllocString(OLESTR("ACV")); pbstr[0][2] = SysAllocString(OLESTR("10")); SafeArrayUnaccessData(*ppOutputArray); }
Quote: > First, you should not access pvData directly. You should use > SafeArrayAccessData and SafeArrayUnaccessData. > Second, your FillData function interprets the array as if it stores an > array of BSTR* pointers, each of which points to an array of BSTRs. It > is not so. Safearray holds one sequential chunk of BSTRs in column-major > order, that is > (0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2) > in your case. Similar to multidimensional arrays in C and C++, only in C > they are stored in row-major order. > -- > With best wishes, > Igor Tandetnik > "For every complex problem, there is a solution that is simple, neat, > and wrong." H.L. Mencken
> > Hi every one I am trying to pass 2D array of string back to VB. > Compile no > > problem but My Application crashes. > > I can Pass 1D String no problem > > Here is my sample code. Pls help me out Is there is any other way to > do it. > > IDL: > > [id(6), helpstring("method ProcessStringArray")] HRESULT > > ProcessStringArray([out]SAFEARRAY (BSTR) *strOutputArray); > > Function Defintion: > > STDMETHODIMP CTestMacroInterface::ProcessStringArray( SAFEARRAY > > **ppOutputArray) > > { > > SAFEARRAYBOUND aDim[2]; > > aDim[0].lLbound = 0; > > aDim[0].cElements = 2; > > aDim[1].lLbound = 0; > > aDim[1].cElements = 3; > > *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); > > FillData((BSTR**)(*ppOutputArray)->pvData); > > } > > void FillData(BSTR** ppMyData) > > { > > ppMyData[0][0] = SysAllocString(OLESTR("SOURCE_VA")); > > ppMyData[0][1] = SysAllocString(OLESTR("ACV")); > > ppMyData[0][2] = SysAllocString(OLESTR("10")); > > ppMyData[1][0] = SysAllocString(OLESTR("SOURCE_VB")); > > ppMyData[1][1] = SysAllocString(OLESTR("ACV")); > > ppMyData[1][2] = SysAllocString(OLESTR("20")); > > }
|
Wed, 14 Jul 2004 05:13:43 GMT |
|
 |
Igor Tandetni #4 / 4
|
 How To pass 2D String array to VB from VC++ Using Safe array
BSTR *pbstr; SafeArrayAccessData(psa, (void**)&pbstr); pbstr[0] = String00; pbstr[1] = String10; pbstr[2] = String01; pbstr[3] = String11; pbstr[4] = String02; pbstr[5] = String12; SafeArrayUnaccessData(psa); where StringIJ is whatever you need to put into [I][J] element. Generally, StringIJ goes into pbstr[I + J*N] where N is the number of rows (to clarify, in my terminology rows go over aDim[0] and columns go over aDim[1]). -- With best wishes, Igor Tandetnik "For every complex problem, there is a solution that is simple, neat, and wrong." H.L. Mencken
Quote: > Thanks Igor > I try the way You suggested. But I want to know How to add the data to the > pointer array > In My function I want ruturn 2 rows and 3 colums string array > STDMETHODIMP > TestMacroInterface::ProcessStringArray( SAFEARRAY**ppOutputArray) > { > HRESULT hresult; > SAFEARRAYBOUND aDim[2] > aDim[0].lLbound = 0; > aDim[0].cElements = 3; > aDim[1].lLbound = 0; > aDim[1].cElements = 2 > BSTR HUGEP *pbstr; > *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); > if (*ppOutputArray==NULL) > { > ::MessageBox(NULL, _T("NOT_OK"), _T("Pickup"), MB_OK); > } > else > hresult=SafeArrayAccessData(*ppOutputArray,(void HUGEP**)&pbstr) > Now How Do I add the data to my BSTR pointer will it work ??? > pbstr[0][0] = SysAllocString(OLESTR("SOURCE_VA")); > pbstr[0][1] = SysAllocString(OLESTR("ACV")); > pbstr[0][2] = SysAllocString(OLESTR("10")); > SafeArrayUnaccessData(*ppOutputArray); > }
> > First, you should not access pvData directly. You should use > > SafeArrayAccessData and SafeArrayUnaccessData. > > Second, your FillData function interprets the array as if it stores an > > array of BSTR* pointers, each of which points to an array of BSTRs. It > > is not so. Safearray holds one sequential chunk of BSTRs in column-major > > order, that is > > (0, 0), (1, 0), (0, 1), (1, 1), (0, 2), (1, 2) > > in your case. Similar to multidimensional arrays in C and C++, only in C > > they are stored in row-major order. > > -- > > With best wishes, > > Igor Tandetnik > > "For every complex problem, there is a solution that is simple, neat, > > and wrong." H.L. Mencken
> > > Hi every one I am trying to pass 2D array of string back to VB. > > Compile no > > > problem but My Application crashes. > > > I can Pass 1D String no problem > > > Here is my sample code. Pls help me out Is there is any other way to > > do it. > > > IDL: > > > [id(6), helpstring("method ProcessStringArray")] HRESULT > > > ProcessStringArray([out]SAFEARRAY (BSTR) *strOutputArray); > > > Function Defintion: > > > STDMETHODIMP CTestMacroInterface::ProcessStringArray( SAFEARRAY > > > **ppOutputArray) > > > { > > > SAFEARRAYBOUND aDim[2]; > > > aDim[0].lLbound = 0; > > > aDim[0].cElements = 2; > > > aDim[1].lLbound = 0; > > > aDim[1].cElements = 3; > > > *ppOutputArray=SafeArrayCreate(VT_BSTR , 2, aDim); > > > FillData((BSTR**)(*ppOutputArray)->pvData); > > > } > > > void FillData(BSTR** ppMyData) > > > { > > > ppMyData[0][0] = SysAllocString(OLESTR("SOURCE_VA")); > > > ppMyData[0][1] = SysAllocString(OLESTR("ACV")); > > > ppMyData[0][2] = SysAllocString(OLESTR("10")); > > > ppMyData[1][0] = SysAllocString(OLESTR("SOURCE_VB")); > > > ppMyData[1][1] = SysAllocString(OLESTR("ACV")); > > > ppMyData[1][2] = SysAllocString(OLESTR("20")); > > > }
|
Wed, 14 Jul 2004 05:37:37 GMT |
|
|
|