- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要在多个程序集中声明相同的接口(interface) - 但不引用公共(public)库。
我对接口(interface)有相同的定义,但是当我尝试从另一个应用程序创建它的实例时出现此错误:
Unable to cast object of type 'myFilter' to type 'DirectShow.IBaseFilter'
(myFilter 声明如下:public class myfilter : DirectSow.IBaseFilter...
)
源对象使用RegAsm.exe注册
两个程序集都有声明:
[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("56a86895-0ad4-11ce-b03a-0020af0ba770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IBaseFilter : IMediaFilter
...
代码被复制,所以IMediaFilter
和所有其他声明完全相同。
我尝试使用这个创建对象的实例:
Type type = Type.GetTypeFromCLSID(new Guid("A3927399-E3AE-41E2-B094-0EA815CC9B9C"));
IBaseFilter filter = (IBaseFilter)Activator.CreateInstance(type);
如何跨程序集转换对象?
最佳答案
根据定义:你不能。两个彼此无关的独立接口(interface)永远不会是彼此"is"的关系,即使它们具有“相同”的命名和相同的成员。
专业的解决方案是在一个独立的程序集中分离接口(interface),然后根据需要引用该程序集的任意多个其他程序集。所有其他都被认为是黑客攻击(在 C#/.NET 中)。
要在这种特殊情况下应用所描述的解决方案,您需要 2 或 3 个程序集:
程序集 #1:(“定义”接口(interface))。这个“定义”是一个 COM 接口(interface)导入这个特殊情况:
[ComImport, System.Security.SuppressUnmanagedCodeSecurity,
Guid("56a86895-0ad4-11ce-b03a-0020af0ba770"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IBaseFilter : IMediaFilter
大会#2: 引用 Assembly #1,并包含一个实现接口(interface)的类
大会#3: 引用 Assembly #1 和 #2,并且可以访问和使用/转换 Assembly #2 中的类。不要(重新)在此处导入接口(interface)。对于 .NET,这将是一个相同但完全“其他”的接口(interface),即使它具有完全相同的成员签名。
我认为 Assembly #1 和 #2 可以合并为一个。确保接口(interface)声明和类定义都是公开的。关键不是导入两次 COM 接口(interface),而是导入一次并引用它。
编辑:反射(reflect)到评论中:
不要将 COM 接口(interface)和类与 .NET 接口(interface)混淆。 (顺便说一下,评论中提到的是类 ID 而不是接口(interface) ID,这在 COM 中是两种不同的东西。)
通过互操作层高度支持访问 .NET 中的 COM 类和接口(interface)。互操作层为您完成所有转换和编码,您可以通过方便的 .NET 接口(interface)访问 COM 组件。然而,这个接口(interface)是在一个(互操作)组件中定义的,并且那些组件(对于众所周知的和经常使用的 COM 组件)是分布式的,或者是原始 COM 东西的一部分下载。因此,从字面上看,它们位于每台 需要的机器上。
还有一个概念差异,在 COM 中,客户端(引用组件)通过 仅 一个 guid(这是类 ID)引用服务器(引用组件),然后请求多态实现一个界面也只有一个guid。因此,客户端可以通过只知道两个 guid 并执行 1-2 个 COM OS 调用来使用组件的特定接口(interface)。这是在互操作层中为您设置的黑盒。在 .NET 中,客户端和服务器之间的绑定(bind)要强得多。
如果您想要定义这种类型的接口(interface),那么您必须做同样的事情:以某种方式在一个程序集中定义该接口(interface),然后将它分发到其他程序集所在的每台机器上正在使用该接口(interface)并引用该接口(interface)。
如果您不接受最佳实践的选项:
您可以使用反射来实现类似的更宽松的绑定(bind),但在这种情况下,这被认为是黑客行为,而且似乎没有必要。准备好您的方法名称和类名称将是字符串,或者至少不正确输入它们不会导致编译错误,但会导致运行时错误。
您还可以在 .NET 中定义和实现 COM 组件,但我认为这不是目标。 COM 是一种遗留(而且很酷)的技术,在当时非常进步(并且没有被理解/批评),但这是超过四分之一个世纪以前(当它被引入时)
关于c# - 如何在单独的库中声明相同的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31051109/
我在覆盖 ReSwift Pod 中的函数时遇到问题。我有以下模拟类(class): import Foundation import Quick import Nimble import RxSwi
我有一个类似于下面的继承结构。我正在采用 Printable 协议(protocol)并努力覆盖 description 属性。我遇到了一个谷歌此时似乎不知道的奇怪错误,提示为第三类,并引用了第二类和
我有一个类“Cat”和 Cat 类的一个子类“DerivedCat”。 Cat 有一个函数 meow(),而 DerivedCat 覆盖了这个函数。 在应用程序中,我声明了一个 Cat 对象: Cat
Kotlin 变量 变量是用于存储数据值的容器。 要创建一个变量,使用 var 或 val,然后使用等号(=)给它赋值: 语法 var 变量名 = 值 val 变量名 = 值 示例 va
C 中的所有标识符在使用前都需要声明,但我找不到它在 C99 标准中表示的位置。 我觉得也是指宏定义,不过定义的只是宏展开顺序。 最佳答案 C99:TC3 6.5.1 §2,脚注 79 明确指出: T
今天我的博客提要显示错误: This page contains the following errors: error on line 2 at column 6: XML declaration
在编写 IIF 语句、表和下面给出的语句时出现错误。 陈述: SELECT IIF(EMP_ID=1,'True','False') from Employee; table : CREATE TAB
我正在创建一个登录 Activity ,我希望它在按下登录按钮时显示进度对话框,我声明、初始化并调用了它,但它没有显示。但是当我在创建时调用进度对话框时,它出现了 这是我的代码: public cla
当我输入声明语句时: Vector distance_vector = new Vector(); 我收到错误(在两种情况下都在“双”下划线): Syntax error on token "doub
我正在本地部署在docker-for-desktop中。这样我将来可以迁移到kubernetes集群。 但是我面临一个问题。使用永久卷时,docker容器/ pod中的目录将被覆盖。 我正在拉最新的S
我有一个 MyObject 类型的对象 obj,我声明了它的实例。 MyObject obj; 但是,我没有初始化它。 MyObject 的类看起来像: public class MyObject {
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 9 年前。 Improv
这个问题已经有答案了: Android: Issue during Arraylist declaration (1 个回答) 已关闭 9 年前。 有时我会看到 ArrayList 声明如下 Arra
我对java比较陌生,经过大量搜索,我无法将相关问题的任何解决方案与我的解决方案配对。我正在尝试实现一种非常简单的方法来写入/读取数组,但编译器无法识别它。 “键盘”也是一个“无法识别的变量”。这是数
简短:何时分配内存 - 在声明或初始化时? 长整型:int x;将占用与int z = 10;相同的内存。 此外,这对于包含更多数据的自定义对象将如何工作。假设我有这个对象: public class
我需要使用此程序更好地理解函数定义、声明和正确调用。我真的需要了解如何使用它们。您能否向我展示编写此程序的正确方法(所有三个都正确并进行解释)? #include #include quad_eq
这是我的主要功能以及我要传递的内容。 int main(void){ struct can elC[7]; // Create an array of stucts Initiali
我想知道是否有更好的方法来完成此任务; 我有一个对象 - 其中一个属性是字典。我有一组逗号分隔值。我需要过滤 Dictionary 并仅获取 Dictionary 值至少与其中一个值匹配的那些元素 这
下面的using-declarations有什么意义 using eoPop::size; using eoPop::operator[]; using eoPop::back; using eoPo
我的问题更像是一个关于 for 循环样式的好奇问题。在阅读别人的一些旧代码时,我遇到了一种我以前从未见过的风格。 var declaredEarlier = Array for(var i=0, le
我是一名优秀的程序员,十分优秀!