Question

Initially, it was probably not proper to create COM through late binding, and then call its methods via InvokeMember. But now, perhaps, too late to redo everything from scratch.

Therefore, tell me how to be.

There is a COM object in the DLL. Written in Delphi7.

In C#, it is used as follows:

Type comType = Type.GetTypeFromProgID(ProgID, false);
object comObj = Activator.CreateInstance(comType);
// and then call methods
comType.InvokeMember("DoLongWork", BindingFlags.InvokeMethod, null, comObj, null);

Now we need to add to it the opportunity to call the methods of the server (i.e. the one who keeps to himself this COM object)

For this, in a COM object in its TLB added additional interface

IHookCallback = interface(IDispatch)
 procedure ServerHook(DoStuff: integer); safecall;
end;

And also, in its main interface added initialization method callback

ITestDisp = dispinterface
...
procedure SetupHook(const Callback: IHookCallback); safecall;

Then imported into the VS project DLL - with this COMom inside. Thereby gained access to the interface description.

Then (in VS) created a class that implements this interface. And I try to transfer it to the COM through InvokeMember

comType.InvokeMember("SetupHook", BindingFlags.InvokeMethod, null, comObj, new object[] {SomeClass as IHookCallback});

and so, too, tried

comType.InvokeMember("SetupHook", BindingFlags.InvokeMethod, null, comObj, new object[] {SomeClass});

I receive an error

Exception has been thrown by the target of an invocation.

InnerException

Specified cast is not valid.

Where did I go wrong?

Was it helpful?

Solution

I did. Write here may be useful to someone my decision.

Initially I have COM object with its own TLB. Written in Delphi 7. There was also a project written in VS 2010. He created the COM using "Activator Class". And then the work was carried out through late binding. Ie through InvokeMember.

The task was this: were ready COM objects, which could not be replaced. Ie was necessary to ensure backward compatibility and work with existing code as before.

But at the same time, you had to write another 2 COM object with advanced features - support several new methods.

I solved this problem as follows: created a separate TLB on Delphi 7. It announced a completely independent interface (inherited from IDispatch but it does not matter). Then I created a new COM object that implements the old interface and the new interface.

Then modified the C #. He also created objects through "Activator Class", but after the establishment immediately brought the created object to the second interface (I imported the description of a second TLB in C # project) with the operator "as". If the result was NULL then it was an old COM does not support the new functionality. Otherwise, we have a new COM with enhanced functionality.

Done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top