【发布时间】:2020-12-29 07:15:00
【问题描述】:
我正在尝试包装 COM API,以便其他人可以使用我的包装器,而无需对包装的 API 有任何了解。但是,我在尝试使用 COM API 中的某些项目时遇到了问题。
假设 COM API 有一个方法可以返回在 API 中定义的对象。
IComChildObject IComObject.GetChildObject()
如果我有对定义 COM API 的 dll 的引用,我可以按如下方式轻松使用它...
IComChildObject childObject = myComObjectInstance.GetChildObject();
我遇到的问题是,我需要能够通过包装类使用 IComChildObject,而无需引用 COM API dll。
我试图在我的包装器中创建一个接口,以实现这一点。所以在我的包装项目中,我有一个这样的界面。
public interface ILocalChildObject : IComChildObject{}
然后我在包装器中添加了一个属性,我认为它可以让我的外部代码使用 IComChildObject。
public class ComWrapper
{
IComObject comObject;
public ILocalChildObject ComChildObject { get { return comObject.GetChildObject() as ILocalChildObject;}}
}
当我从外部代码运行以下代码时,ChildObject 为空
ILocalChildObject ChildObject = myComWrapper.ComChildObject;
我显然做错了什么,但我对此一头雾水,甚至不知道要在 Google 上搜索什么。
也许我不清楚我要做什么,或者我正试图在这里做一些奇怪的事情。我想以这样的方式创建一个包装类库,使用它的代码不必知道任何关于包装的库。到目前为止,我做得很好,直到我需要在外部代码中使用包装库中的对象。我可以通过在外部项目中引用包装库轻松解决此问题,但我想避免这样做。
基本上,我只需要一种在我的外部代码中使用 IComChildObject 的方法,而无需添加对 COM API dll 的引用。
任何帮助将不胜感激,
【问题讨论】:
-
如果您的 API 基于 IDispatch,您可以使用
dynamic关键字(尚未在 .NET 核心上)docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/… 或 Type.Invoke("name")。如果不是(如果它基于 IUnknown),那么您必须在外部 dll 或 .tlb 中或直接在 C# 代码中声明此接口,以便.NET 运行时调用它。 -
@SimonMourier 感谢您的帮助。我如何知道 API 的基础是什么?我无法控制 API,只能通过 COM 访问它。我唯一可以更改的代码是包装器代码,以及使用包装器的代码。
-
@SimonMourier 谢谢你的帮助。我使用了动态,它起作用了。如果您将您的评论转换为答案,我将接受它作为正确答案。
-
接口不是包装器,不会隔离互操作程序集引用。你需要一堂课。假设具有 IComChildObject 类型的私有字段的 ChildWrapper。就像您对 ComWrapper 所做的那样。这确实很无聊,当您看到自己必须用单行复制所有子对象属性和方法时,您会开始想知道这可能是什么意思。倾向于了解更多有关您包装的库的信息,但不起作用。