Need help with a MFC client with SAFEARRAY argument 
Author Message
 Need help with a MFC client with SAFEARRAY argument

MFC client access a VB COM Server with SAFEARRAY argument
Hi all,

I am writing a personal program and ran into a major ostacle. I tried it for
over and can not figure it out. I would appreciate any comment and help from
you guys.

I am writing a MFC program. This program will interface a vendor program
which ONLY provide VB support. Actually the vendor program was written in VB
obviousely.

I have no problem if the method does not have a SAFEARRAY argument. However,
many methods have SAFEARRAY arguments. Even worse, this program only allow
you to do late-binding, no TLibrary is provided.

For example, one method called
Sub GetAllChartListSorts(SortNames() As String)

Sound simple, but if I write code like this -
OLECHAR FAR* szMember2 = L"GetAllChartListSorts";
hr=m_server.m_lpDispatch->GetIDsOfNames( IID_NULL, &szMember2, 1,
LOCALE_USER_DEFAULT, &dispid);
VARIANT return_val;
EXCEPINFO ExceptionInfo;
unsigned int uArgErr;
DISPPARAMS dp;

VariantInit(&return_val);
//create DISPPARAMS struct
dp.cArgs = 1;
dp.rgvarg = new VARIANTARG;

dp.rgvarg->vt=VT_ARRAY|VT_BSTR;
dp.rgvarg->parray = NULL;

dp.cNamedArgs = 0;
dp.rgdispidNamedArgs = NULL;

//invoke the call
hr = m_server.m_lpDispatch->Invoke( dispid, IID_NULL,
LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD, &dp, &return_val, &ExceptionInfo,
&uArgErr);

The method call return S_OK, but I can find nothing in the DISPARAMS. The
array is not filled up.

The Visual Basic client works just fine.

dim a() as String
Server.GetAllChartListSorts a()

I doubted that the SAFEARRAY might not be properly filled. I verified that
by implementing a COM Server and let a VB client sends a dynamic array
argument. It proves that my way of filling was correct.

However, the code does work. Anything wrong here?



Mon, 13 Dec 2004 20:43:09 GMT  
 Need help with a MFC client with SAFEARRAY argument
Hi Sherwood,

Try using this code as a test:

DISPID id = 1L;  // Substitute your number here
VARIANTARG* pvars = new VARIANTARG[1];
pvars[0].bstrVal = str.AllocSysString();
pvars[0].vt = VT_BSTR;
VARIANT varResult;
VariantInit(&varResult);
DISPPARAMS disp = { pvars, NULL, 1, 0 };
pDispatch->Invoke(id, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD,
&disp, &varResult, NULL, NULL);
// set a breakpoint on the following line
delete[] pvars;

Now, when this comes back, the variant's .vt should have changed to an
array of some sort.  And the variant's union pointer will have taken a
new value.  The null BSTR we passed in will have been discarded.

If this doesn't work, then pass in a null INITIALIZED array of BSTR's
instead of a single.  Once this works, then work your way back to your
previous (better) method of identifying the DISPID.

Hope this helps,
Kurt



Quote:
>MFC client access a VB COM Server with SAFEARRAY argument
>Hi all,

>I am writing a personal program and ran into a major ostacle. I tried it for
>over and can not figure it out. I would appreciate any comment and help from
>you guys.

>I am writing a MFC program. This program will interface a vendor program
>which ONLY provide VB support. Actually the vendor program was written in VB
>obviousely.

>I have no problem if the method does not have a SAFEARRAY argument. However,
>many methods have SAFEARRAY arguments. Even worse, this program only allow
>you to do late-binding, no TLibrary is provided.

>For example, one method called
>Sub GetAllChartListSorts(SortNames() As String)

>Sound simple, but if I write code like this -
>OLECHAR FAR* szMember2 = L"GetAllChartListSorts";
>hr=m_server.m_lpDispatch->GetIDsOfNames( IID_NULL, &szMember2, 1,
>LOCALE_USER_DEFAULT, &dispid);
>VARIANT return_val;
>EXCEPINFO ExceptionInfo;
>unsigned int uArgErr;
>DISPPARAMS dp;

>VariantInit(&return_val);
>//create DISPPARAMS struct
>dp.cArgs = 1;
>dp.rgvarg = new VARIANTARG;

>dp.rgvarg->vt=VT_ARRAY|VT_BSTR;
>dp.rgvarg->parray = NULL;

>dp.cNamedArgs = 0;
>dp.rgdispidNamedArgs = NULL;

>//invoke the call
>hr = m_server.m_lpDispatch->Invoke( dispid, IID_NULL,
>LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD, &dp, &return_val, &ExceptionInfo,
>&uArgErr);

>The method call return S_OK, but I can find nothing in the DISPARAMS. The
>array is not filled up.

>The Visual Basic client works just fine.

>dim a() as String
>Server.GetAllChartListSorts a()

>I doubted that the SAFEARRAY might not be properly filled. I verified that
>by implementing a COM Server and let a VB client sends a dynamic array
>argument. It proves that my way of filling was correct.

>However, the code does work. Anything wrong here?



Mon, 13 Dec 2004 22:32:19 GMT  
 Need help with a MFC client with SAFEARRAY argument
As far the the Type Library is concerned, why not use the #Import statement?

Here's how I do it in my C++ program:

   SAFEARRAY *Image;
   float *Img;//points to the data in the SAFEARRAY Image

   mFFTptr->get_Image(&Image);//get a pointer to a SAFEARRAY
   SafeArrayAccessData(Image,(void**)&Img);//get at the values


Quote:
> MFC client access a VB COM Server with SAFEARRAY argument
> Hi all,

> I am writing a personal program and ran into a major ostacle. I tried it
for
> over and can not figure it out. I would appreciate any comment and help
from
> you guys.

> I am writing a MFC program. This program will interface a vendor program
> which ONLY provide VB support. Actually the vendor program was written in
VB
> obviousely.

> I have no problem if the method does not have a SAFEARRAY argument.
However,
> many methods have SAFEARRAY arguments. Even worse, this program only allow
> you to do late-binding, no TLibrary is provided.

> For example, one method called
> Sub GetAllChartListSorts(SortNames() As String)

> Sound simple, but if I write code like this -
> OLECHAR FAR* szMember2 = L"GetAllChartListSorts";
> hr=m_server.m_lpDispatch->GetIDsOfNames( IID_NULL, &szMember2, 1,
> LOCALE_USER_DEFAULT, &dispid);
> VARIANT return_val;
> EXCEPINFO ExceptionInfo;
> unsigned int uArgErr;
> DISPPARAMS dp;

> VariantInit(&return_val);
> //create DISPPARAMS struct
> dp.cArgs = 1;
> dp.rgvarg = new VARIANTARG;

> dp.rgvarg->vt=VT_ARRAY|VT_BSTR;
> dp.rgvarg->parray = NULL;

> dp.cNamedArgs = 0;
> dp.rgdispidNamedArgs = NULL;

> //invoke the call
> hr = m_server.m_lpDispatch->Invoke( dispid, IID_NULL,
> LOCALE_SYSTEM_DEFAULT,DISPATCH_METHOD, &dp, &return_val, &ExceptionInfo,
> &uArgErr);

> The method call return S_OK, but I can find nothing in the DISPARAMS. The
> array is not filled up.

> The Visual Basic client works just fine.

> dim a() as String
> Server.GetAllChartListSorts a()

> I doubted that the SAFEARRAY might not be properly filled. I verified that
> by implementing a COM Server and let a VB client sends a dynamic array
> argument. It proves that my way of filling was correct.

> However, the code does work. Anything wrong here?



Tue, 14 Dec 2004 06:19:53 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Need help with a MFC client with SAFEARRAY argument

2. MFC client access a VB COM Server with SAFEARRAY argument

3. MFC client access a VB COM Server with SAFEARRAY argument

4. Need Help Passing a Variant SafeArray to ASP from C++/ATL Object

5. Need help with SAFEARRAY

6. C++, Visual Basic and SAFEARRAY: Need HELP!

7. SAFEARRAY as event argument

8. SAFEARRAY Argument Problems

9. I need a sample of Https,SSL,mfc client

10. Releasing SAFEARRAY from VB Client (to a DCOM Object)

11. Problem with VB clients accessing SAFEARRAY passed from my ATL server

12. Passing a 2D SafeArray from VB client to ATL COM component

 

 
Powered by phpBB® Forum Software