15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


OLE Automation: 32-bit client and 16-bit server

anatoly.katzman@octel.com
Tuesday, November 19, 1996

  Environment: VC++ 1.52c, VC++ 4.2, NT 4.0, Windows 95
  
  I need to have a mixed OLE Automation pair: the client is 32-bit and written 
  in VC++ 4.2, whereas the server is 16-bit and written using VC++ 1.52.
  
  For a 32-bit server it would be easy: VC 4.2 automatically generates an .ODL 
  file and then a type library (.TLB). On the client side, a server proxy can be 
  easily created by ClassWizard from that type library.
  
  In VC 1.52, I didn't find a way to generate an .ODL file automatically, and 
  without it I can't get a .TLB...
  Does it mean that I have to write the .ODL manually ? Or there still is an 
  automatic way to get an .ODL like other ClassWizard deliverables ? 
  
  Thanks in advance.
  
  Anatoly Katzman



Carl Gunther -- cgunther@ix.netcom.com
Thursday, November 21, 1996

Anatoly,

The salient aspect of the problem you describe is that the
server is 16-bit; it seems to make little difference whether the
client is 32-bit or 16-bit.  The problem is that VC++ 1.52 does
not seem to generate an ODL or TLB file automatically.

I've played around with getting a 16-bit server talking to a
16-bit client, and ran across the same problem.  I found a
way to deal with it for my toy test program that relies
heavily on the fact that I control the source for both the
server and the client.  This solution does not require
the creation of an ODL file.  Instead, it relies upon direct
manual editing of interface functions in the client to
match up with functions exposed by the server.
This may not be very maintainable if expanded to a large interface.

Here's the basic, quite simple, approach.  You create your server
and its interface functions.  You note the ordinal position of 
each declared function in the dispatch map macro section maintained
by Class Wizard, e.g.,

BEGIN_DISPATCH_MAP(CServerInterface, CCmdTarget)
	//{{AFX_DISPATCH_MAP(CServerInterface)
	DISP_FUNCTION(CServerInterface, "Func1", GetCompositeImageFile, 
			VT_BSTR, VTS_BSTR VTS_I2)
	DISP_FUNCTION(CServerInterface, "Func2", GetCompositeImageFile, 
			VT_BSTR, VTS_BSTR VTS_I2)
	DISP_FUNCTION(CServerInterface, "Func3", GetCompositeImageFile, 
			VT_BSTR, VTS_BSTR VTS_I2)
	//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()

(The above functions just happen to have the same argument and 
return types).

Now, I've observed that the dispatch IDs assigned by the dispatch
map macro start at 0x1 for the first function declared, and
increment by one for each function as you go down the list
(since VC 1.52 is probably the very last 16-bit version of VC++
we will ever see, do we really have to worry about this changing?).
So, in the above example, Func1 gets an ID of 0x01, Func2 gets
an ID of 0x02, etc.

Therefore, in your client, you can simply manually
create a class IInterfaceToServer (derived from COleDispatchDriver)
to wrap your interface to the server object with access functions as 
follows:

CString IInterfaceToServer::Func1(LPCTSTR strArg, short shortArg)
{
	CString result;
	static BYTE BASED_CODE parms[] =
		VTS_BSTR VTS_I2;
	InvokeHelper(0x1, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
			parms, strArg, shortArg);
	return result;
}


CString IInterfaceToServer::Func2(LPCTSTR strArg, short shortArg)
{
	CString result;
	static BYTE BASED_CODE parms[] =
		VTS_BSTR VTS_I2;
	InvokeHelper(0x2, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
			parms, strArg, shortArg);
	return result;
}


CString IInterfaceToServer::Func3(LPCTSTR strArg, short shortArg)
{
	CString result;
	static BYTE BASED_CODE parms[] =
		VTS_BSTR VTS_I2;
	InvokeHelper(0x3, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
			parms, strArg, shortArg);
	return result;
}


Note that the each function returns a string, and takes
two arguments:  a string and a short.  Note the 0x01,
0x02, and 0x03 progression of dispatch IDs which is the
only difference between these functions apart from their names.

Adding a new function to the server should not require any 
changes to the client, as long as you allow it to be added to 
the end of the dispatch map (which should happen automatically
so long as you don't manually edit the ClassWizard-generated
section).  Deleting a function is another matter entirely:
you'll have to update the IDs manually in your client in this
case.

Perhaps someone else has a better approach (I certainly hope so!)
but this one has been tried, and it "works."

Good luck,

Carl

anatoly.katzman@octel.com wrote:
> 
>   Environment: VC++ 1.52c, VC++ 4.2, NT 4.0, Windows 95
> 
>   I need to have a mixed OLE Automation pair: the client is 32-bit and written
>   in VC++ 4.2, whereas the server is 16-bit and written using VC++ 1.52.
> 
>   For a 32-bit server it would be easy: VC 4.2 automatically generates an .ODL
>   file and then a type library (.TLB). On the client side, a server proxy can be
>   easily created by ClassWizard from that type library.
> 
>   In VC 1.52, I didn't find a way to generate an .ODL file automatically, and
>   without it I can't get a .TLB...
>   Does it mean that I have to write the .ODL manually ? Or there still is an
>   automatic way to get an .ODL like other ClassWizard deliverables ?
> 
>   Thanks in advance.
> 
>   Anatoly Katzman

-- 
Check out the extensive Website of the Labor/Community Strategy Center
at http://www.igc.apc.org/lctr/

Check out the Website of Songs for Social Change
at http://globalvisions.org/cl/sfsc/

Copyright 1996 Carl E. Gunther.  Permission to reproduce this message
in text form for not-for-profit purposes freely granted provided that 
the preceeding copyright notice is retained.




Michael McIntosh -- mmcintosh@acm.org
Monday, November 25, 1996

I ran into this same problem a while back. The ugly soultion I used was to
use
AppWizard/ClassWizard to generate a 32bit server with the same interface as
my 16bit server. I then used it's ODL file (after changing the GUIDs
appropriately)
to generate the TLB that was used in the 32bit client.

Hope you find a better way,
Mike McIntosh 

----------
> From: Carl Gunther 
> To: mfc-l@netcom.com
> Subject: Re: OLE Automation: 32-bit client and 16-bit server
> Date: Thursday, November 21, 1996 5:23 AM
> 
> Anatoly,
> 
> The salient aspect of the problem you describe is that the
> server is 16-bit; it seems to make little difference whether the
> client is 32-bit or 16-bit.  The problem is that VC++ 1.52 does
> not seem to generate an ODL or TLB file automatically.
> 
> I've played around with getting a 16-bit server talking to a
> 16-bit client, and ran across the same problem.  I found a
> way to deal with it for my toy test program that relies
> heavily on the fact that I control the source for both the
> server and the client.  This solution does not require
> the creation of an ODL file.  Instead, it relies upon direct
> manual editing of interface functions in the client to
> match up with functions exposed by the server.
> This may not be very maintainable if expanded to a large interface.
> 
> Here's the basic, quite simple, approach.  You create your server
> and its interface functions.  You note the ordinal position of 
> each declared function in the dispatch map macro section maintained
> by Class Wizard, e.g.,
> 
> BEGIN_DISPATCH_MAP(CServerInterface, CCmdTarget)
> 	//{{AFX_DISPATCH_MAP(CServerInterface)
> 	DISP_FUNCTION(CServerInterface, "Func1", GetCompositeImageFile, 
> 			VT_BSTR, VTS_BSTR VTS_I2)
> 	DISP_FUNCTION(CServerInterface, "Func2", GetCompositeImageFile, 
> 			VT_BSTR, VTS_BSTR VTS_I2)
> 	DISP_FUNCTION(CServerInterface, "Func3", GetCompositeImageFile, 
> 			VT_BSTR, VTS_BSTR VTS_I2)
> 	//}}AFX_DISPATCH_MAP
> END_DISPATCH_MAP()
> 
> (The above functions just happen to have the same argument and 
> return types).
> 
> Now, I've observed that the dispatch IDs assigned by the dispatch
> map macro start at 0x1 for the first function declared, and
> increment by one for each function as you go down the list
> (since VC 1.52 is probably the very last 16-bit version of VC++
> we will ever see, do we really have to worry about this changing?).
> So, in the above example, Func1 gets an ID of 0x01, Func2 gets
> an ID of 0x02, etc.
> 
> Therefore, in your client, you can simply manually
> create a class IInterfaceToServer (derived from COleDispatchDriver)
> to wrap your interface to the server object with access functions as 
> follows:
> 
> CString IInterfaceToServer::Func1(LPCTSTR strArg, short shortArg)
> {
> 	CString result;
> 	static BYTE BASED_CODE parms[] =
> 		VTS_BSTR VTS_I2;
> 	InvokeHelper(0x1, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
> 			parms, strArg, shortArg);
> 	return result;
> }
> 
> 
> CString IInterfaceToServer::Func2(LPCTSTR strArg, short shortArg)
> {
> 	CString result;
> 	static BYTE BASED_CODE parms[] =
> 		VTS_BSTR VTS_I2;
> 	InvokeHelper(0x2, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
> 			parms, strArg, shortArg);
> 	return result;
> }
> 
> 
> CString IInterfaceToServer::Func3(LPCTSTR strArg, short shortArg)
> {
> 	CString result;
> 	static BYTE BASED_CODE parms[] =
> 		VTS_BSTR VTS_I2;
> 	InvokeHelper(0x3, DISPATCH_METHOD, VT_BSTR, (void*)&result, 
> 			parms, strArg, shortArg);
> 	return result;
> }
> 
> 
> Note that the each function returns a string, and takes
> two arguments:  a string and a short.  Note the 0x01,
> 0x02, and 0x03 progression of dispatch IDs which is the
> only difference between these functions apart from their names.
> 
> Adding a new function to the server should not require any 
> changes to the client, as long as you allow it to be added to 
> the end of the dispatch map (which should happen automatically
> so long as you don't manually edit the ClassWizard-generated
> section).  Deleting a function is another matter entirely:
> you'll have to update the IDs manually in your client in this
> case.
> 
> Perhaps someone else has a better approach (I certainly hope so!)
> but this one has been tried, and it "works."
> 
> Good luck,
> 
> Carl
> 
> anatoly.katzman@octel.com wrote:
> > 
> >   Environment: VC++ 1.52c, VC++ 4.2, NT 4.0, Windows 95
> > 
> >   I need to have a mixed OLE Automation pair: the client is 32-bit and
written
> >   in VC++ 4.2, whereas the server is 16-bit and written using VC++
1.52.
> > 
> >   For a 32-bit server it would be easy: VC 4.2 automatically generates
an .ODL
> >   file and then a type library (.TLB). On the client side, a server
proxy can be
> >   easily created by ClassWizard from that type library.
> > 
> >   In VC 1.52, I didn't find a way to generate an .ODL file
automatically, and
> >   without it I can't get a .TLB...
> >   Does it mean that I have to write the .ODL manually ? Or there still
is an
> >   automatic way to get an .ODL like other ClassWizard deliverables ?
> > 
> >   Thanks in advance.
> > 
> >   Anatoly Katzman
> 
> -- 
> Check out the extensive Website of the Labor/Community Strategy Center
> at http://www.igc.apc.org/lctr/
> 
> Check out the Website of Songs for Social Change
> at http://globalvisions.org/cl/sfsc/
> 
> Copyright 1996 Carl E. Gunther.  Permission to reproduce this message
> in text form for not-for-profit purposes freely granted provided that 
> the preceeding copyright notice is retained.




| Вернуться в корень Архива |