Hello *,
I'm trying to implement a simple COM Server with Dolphin 5 XP that can be used from a Visual C++ client application. The MIDL is created with Visual C++ 6.0: // wowTest.odl : Quellcode der Typbibliothek für wowTest.dll // Diese Datei wird vom MIDL-Compiler bearbeitet, um die // Typbibliothek zu erzeugen (wowTest.tlb). [ uuid(74455811-D806-42F3-A789-01832C42523C), version(1.0) ] library WowTest { importlib("stdole32.tlb"); importlib("stdole2.tlb"); // Primary dispatch interface for Test [ uuid(7670CCD4-164D-4473-A486-04397772EE53) ] dispinterface ITest { properties: // NOTE - ClassWizard will maintain property information here. // Use extreme caution when editing this section. //{{AFX_ODL_PROP(Test) //}}AFX_ODL_PROP methods: // NOTE - ClassWizard will maintain method information here. // Use extreme caution when editing this section. //{{AFX_ODL_METHOD(Test) [id(1)] long count(); [id(2)] long add(long l1, long l2); //}}AFX_ODL_METHOD }; // Class information for Test [ uuid(57B71FF5-281D-4D45-8DBE-67F570842BB8) ] coclass Test { [default] dispinterface ITest; }; //{{AFX_APPEND_ODL}} //}}AFX_APPEND_ODL}} }; The corresponding typelibrary is imported into the Dolphin image with the Active X Component Wizard. The COM Object is implemented in the class WowTestImpl: AXDualImp subclass: #WowTestImpl instanceVariableNames: 'm_count' classVariableNames: '' poolDictionaries: '' classInstanceVariableNames: '' instance methods: supportedInterfaces ^Array with: WowTestITest interfaceClass ^WowTestITest initialize m_count := 0. count m_count := m_count + 1. ^m_count add: l1 l2: l2 ^l1 + l2 class methods: progID ^'WowTest.Test.1' clsid ^CLSID fromString: '{57B71FF5-281D-4D45-8DBE-67F570842BB8}' The implementation is registered with: WowTestImpl registerClassFactory. WowTestImpl register. If I start a client from Visual C++ or Dolphin inside, a WowTestImpl object is created and initialize. But an ivocation of the count or add method results in an COM Exception "HRESULT Error: Member not found. (Facility_Dispatch) What goes wrong ? |
"Wolfgang Wunderlich" <[hidden email]> wrote in message
news:[hidden email]... > Hello *, > > I'm trying to implement a simple COM Server with Dolphin 5 XP that can > be used from a Visual C++ client application. > > The MIDL is created with Visual C++ 6.0: > >... > > // Primary dispatch interface for Test > > [ uuid(7670CCD4-164D-4473-A486-04397772EE53) ] > dispinterface ITest > { > .... > The corresponding typelibrary is imported into the Dolphin image with > the Active X Component Wizard. > > The COM Object is implemented in the class WowTestImpl: > > AXDualImp subclass: #WowTestImpl > instanceVariableNames: 'm_count' > classVariableNames: '' > poolDictionaries: '' > classInstanceVariableNames: '' > ... > > If I start a client from Visual C++ or Dolphin inside, a WowTestImpl > object is created and initialize. But an ivocation of the count or add > method results in an COM Exception > > "HRESULT Error: Member not found. (Facility_Dispatch) > > What goes wrong ? ITest is not a 'dual' interface, but a pure dispatch interface, or 'dispinterface'. AXDualImp uses the generic capability of a typelibrary to dispatch late-bound calls through IDispatch to the "custom" side of a dual interface, but since ITest has no custom side, this will not work. It is possible to implement pure dispinterfaces in Dolphin, but you have to take care of mapping between integer dispatch ids and the appropriate implementation methods. This is straightforward enough using a dictionary, or pair of dictionaries, for the mapping, and #perform:withArguments: for dispatching, but when calls come in via IDispatch a component has to be prepared to coerce arguments from the types passed in to the types it is expecting. The preferred method is to implement a dual interface, and if you are in control of the interface design then I suggest that you do this. Pure dispinterfaces have many disadvantages, not the least of which is poor performance. The majority of programming environments will use the early-bound/custom part of the dual interface by preference, and for those that do not the typelibrary can provide a painless implementation of IDispatch just by subclassing off AXDualImp as you have done, although the override of #supportedInterfaces is not needed. In fact you need only override #interfaceClass, and provide an implementation of the interface methods. Regards Blair |
Free forum by Nabble | Edit this page |