- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经通过 COM-Interop 将一些事件从用 C# 编写的库公开到 C++ 库。一切正常,但我想以 COM 样式对该库进行版本控制。当我尝试执行此操作时遇到了障碍 - 我无法更改(设置)从该库的 TLB 导入的 TLH 文件中的 SampleEventArgs
类的 GUID。下面是一个最小的工作示例。
在 C# 中实现所需的接口(interface)和类:
[Guid("37B8697D-BC5F-4CCB-8002-5F734B4765C8")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class SampleEventArgs : EventArgs
{
public int Count { set; get; }
}
[Guid("8F6E11DE-C892-4540-89C0-C59F628ABC20")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISampleInterface
{
[DispId(1)]
void SampleMethod(object sender, SampleEventArgs e);
}
[Guid("945B64A6-B4E5-48E7-9DB0-89BF92DCFD0C")]
[ComSourceInterfaces(typeof(ISampleInterface))]
[ComVisible(true)]
public class SampleClass
{
public void SampleMethod()
{
SampleEventArgs args = new SampleEventArgs() { Count = 0 };
sampleEventHandler(this, args);
}
public event SampleEventHandler sampleEventHandler;
}
public delegate void SampleEventHandler(object sender, SampleEventArgs e);
将TLB文件导入C++工程生成TLH文件:
#import "C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb"
#import "com_interop_dll.tlb"
部分生成的TLH文件:
//
// Forward references and typedefs
//
struct __declspec(uuid("23ece2ab-6e98-4301-8fff-eed74151d585"))
/* LIBID */ __com_interop_dll;
struct /* coclass */ SampleEventArgs;
struct /* coclass */ SampleClass;
struct __declspec(uuid("599c264e-506e-3780-97b6-c1edff5f4a66"))
/* dual interface */ _SampleEventArgs;
struct __declspec(uuid("e82fc089-4301-3c69-bd80-4328a85b6314"))
/* dual interface */ _SampleClass;
我的问题是如何在 C# 代码中为 _SampleEventArgs
设置 GUID?我相信,此 GUID ("599c264e-506e-3780-97b6-c1edff5f4a66"
) 是自动生成的,并且可以手动设置此值。
最佳答案
只有声明了自己的接口(interface)才能控制[Guid]。在 COM 中非常重要,客户端代码总是与接口(interface)一起工作,并且实现总是隐藏的。按照您现在的做法,类型库导出器被迫根据类声明创建合成接口(interface)。
不可避免地,它还必须自动生成接口(interface)的 IID。否则不是坏事,接口(interface)在 COM 中是不可变的,如果您进行任何更改,那么您必须也更改 IID。
另请注意,您暴露的太多了,这是您必须导入 mscorlib.tlb 的原因。那不是很好。它是必需的,因为自动生成的接口(interface)还包括从 System.Object 继承的成员。在你的情况下是 EventArgs。这些对客户端代码都没有用。所以让它像这样:
[Guid("599c264e-506e-3780-97b6-c1edff5f4a66")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface ISampleEventArgs {
int Count { set; get; }
}
客户端必须实现此接口(interface)才能获取事件,无需公开您的实现:
[ComVisible(false)]
public class SampleEventArgs : EventArgs, ISampleEventArgs
{
public int Count { set; get; }
}
更改 ISampleInterface.SampleMethod 以公开 ISampleEventArgs。并编写 ISampleClass,方法相同。为 SampleClass 提供 [ClassInterface(ClassInterfaceType.None)] 属性,您将不再依赖 mscorlib.tlb
关于c# - 如何更改/设置从 TLB (TLH) 中的 EventArgs 继承的 COM 类的 GUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34753045/
我有一个当前定义的没有事件参数的事件。即它发送的EventArgs是EventArgs.Empty。 在这种情况下,最简单的方法是将我的事件处理程序声明为: EventHandler MyCustom
我了解使用带有签名 delegate void delegate_name(object sender, EventArgs e) 的委托(delegate)类型的事件的好处 a) 但除了它可以节省我
我正在使用这种方式从 XAML 中捕获事件: 这种方式很有效,我可以在我的代码中触发我的 ChangeValue 函数。但我想知道我的 ChangeValue
我的一些代码中有 protected override void OnFormClosing(FormClosingEventArgs e),代码分析给出了 CA1062,因为我不检查 e 是否为 n
C#语言中的java等价方法“getSource()”是什么 public void actionPerformed(ActionEvent e) { if(e.getSource().equa
这个问题在这里已经有了答案: Aliasing / Shortening the Namespaces in .NET (2 个答案) 关闭 6 年前。 是否可以为某些类型声明缩写,例如 Depen
我有一个引发事件的类。我希望订阅者能够修改在 EventArgs 中传递的值。 在引发事件的类中: class Factory { public event EventHand
我有一个非常基本的事件: public event EventHandler OnAborted; 我需要做的就是调用这个事件,我什至不需要提供任何参数,所以没什么特别的。我对 EventArgs 参
我正在开发 Windows 窗体应用程序,我想将类型为 MouseEventArgs 的参数传递给 Picturebox 上的 MouseClick 事件EventArgs,但当我这样做时,调试器会为
我有多个具有相同设计的表单,例如: In Form1{ Form2 = new Formtoopen(); Form2.Resize += new EventHandler(Form2_Resize)
我正在学习 C# 中的事件,并且了解 EventArgs 类包含有关事件的数据。但是我很难理解为什么 EventArgs 是必要的。 例如,在 this MSDN example 中,WakeMeUp
我有点懵。我知道我可以创建从 EventArgs 派生的类以获得自定义事件数据。但是我能以某种方式使用基类 EventArgs 吗?就像鼠标按钮点击一样,在订阅者方法中,总是有“EventArgs e
我正在重构的类库有大量事件(超过 50 个),每个事件都有自己的委托(delegate),尽管许多事件具有相同的参数。我开始将它们全部切换为使用 EventHandler 和自定义 EventArgs
海报在 Are EventArg classes needed now that we have generics和 Does .NET have a built-in EventArgs?建议不要使
考虑这个函数签名: Private Void TextBox1_TextChange(Object Sender, EventArgs e) 据我所知,我的理解如下。 private是修饰符 返回类型
在 .NET 应用程序中,事件通常以这种方式连接: public event EventHandler OnChange { add { _dependency.OnC
经典的通用 C# 事件具有以下参数: (object sender, EventArgs e) 我可以为 e 参数实现一个具有更具体签名的事件,为 EventArgs 派生。 现在,像 EventAr
我正在学习 WPF/Silverlight,并在 MS 视频广播中看到现在建议使用 RoutedEventArgs超过 EventArgs ;虽然它没有确切说明原因。 我有一个 win forms 应
我有一个用户控件,它在与 Web 服务通信后引发事件。父级在引发时处理此事件。我认为正确的方法是将从网络服务返回的对象作为 eventargs 传递给父级??? 如果这是正确的方法,我似乎无法找到有关
我正在开发一款游戏只是为了好玩,我正在尝试实现事件但出现错误: Error CS0305: Using the generic type 'Game.NPC.Events.MurderEventArg
我是一名优秀的程序员,十分优秀!