简体   繁体   English

通过COM接口时出错

[英]Error when pass COM interface

Initially, it was probably not proper to create COM through late binding, and then call its methods via InvokeMember. 最初,通过后期绑定创建COM,然后通过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. DLL中有一个COM对象。 Written in Delphi7. 用Delphi7写。

In C#, it is used as follows: 在C#中,其用法如下:

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 (ie the one who keeps to himself this COM object) 现在,我们需要增加调用服务器方法的机会(即,将这个COM对象保留给自己的那个)

For this, in a COM object in its TLB added additional interface 为此,在其TLB的COM对象中添加了附加接口

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. 然后导入到VS项目DLL中-带有此COMom。 Thereby gained access to the interface description. 从而获得对接口描述的访问。

Then (in VS) created a class that implements this interface. 然后(在VS中)创建了一个实现此接口的类。 And I try to transfer it to the COM through InvokeMember 我尝试通过InvokeMember将其传输到COM

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? 我哪里做错了?

I did. 是的 Write here may be useful to someone my decision. 在这里写可能对我的决定有用。

Initially I have COM object with its own TLB. 最初,我有自己的TLB COM对象。 Written in Delphi 7. There was also a project written in VS 2010. He created the COM using "Activator Class". 用Delphi 7编写。还有一个用VS 2010编写的项目。他使用“ Activator Class”创建了COM。 And then the work was carried out through late binding. 然后通过后期装订完成了工作。 Ie through InvokeMember. 即通过InvokeMember。

The task was this: were ready COM objects, which could not be replaced. 任务是这样的:准备好无法替换的COM对象。 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. 但是同时,您还必须编写另一个具有高级功能的2 COM对象-支持多种新方法。

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). 我解决了以下问题:在Delphi 7上创建了一个单独的TLB。它宣布了一个完全独立的接口(从IDispatch继承,但没有关系)。 Then I created a new COM object that implements the old interface and the new interface. 然后,我创建了一个新的COM对象,该对象实现了旧接口和新接口。

Then modified the C #. 然后修改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". 他还通过“ Activator Class”创建了对象,但是在建立之后,立即用运算符“ as”将创建的对象带到第二个接口(我在C#项目中导入了第二个TLB的描述)。 If the result was NULL then it was an old COM does not support the new functionality. 如果结果为NULL,则表明它是旧的COM,不支持新功能。 Otherwise, we have a new COM with enhanced functionality. 否则,我们将拥有一个具有增强功能的新COM。

Done. 完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM