【问题标题】:C# COM Library: How to Decorate Interop Function Lines for ActiveX / COM VisibilityC# COM 库:如何装饰 ActiveX / COM 可见性的互操作函数行
【发布时间】:2014-01-16 07:36:57
【问题描述】:

我还没有在 StackOverflow 上看到答案。这是在具有下面定义的接口(和项目设置)的 C# 库项目中,因此它作为 COM 组件可见。

目标是通过 COM 接口使互操作行中的函数/方法可见。互操作行提供对旧 C 库/dll 中函数的可见性。

问题通过下面 NativeCalls 类中的 Convert 的互操作行显示。它包括“静态外部”。如果这些(即“静态外部”)包含在类定义上方的接口部分中(如图所示),我会收到错误:

  • 修饰符“extern”对此项无效
  • 修饰符“静态”对此项无效

如果我删除“extern static”,类中将找不到接口部分中的“Convert”。

如何装饰接口部分中的“Convert”行,这样我就不需要在 NativeCalls 类中编写额外的方法来包装每个互操作行(即那些以“public static extern”开头的方法,例如“转换”。如果我需要这样做,我有数百个要包装 - 也许一个不错的宏程序是为了:)。什么是更好/更短的方法?感谢您的帮助。

[ComVisible(true)]
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83D")]
  public interface IComNativeCallsInterface
{
    [DispId(1)]
    static extern int Convert(ref formatfile fptr); // leaving "static extern" on front causes errors. Removing "static extern" will cause the call "Convert" to not be found in the class.
}

[Guid("7BD20046-DF8C-44A6-8F6B-687FAA26FA7D"),
    InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IComNativeCallsEventsInterface
{
}

[ComVisible(true)]
[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F93D"),
    ClassInterface(ClassInterfaceType.None),
    ComSourceInterfaces(typeof(IComNativeCallsEventsInterface))]
public class NativeCalls : IComNativeCallsInterface
{
    /// Return Type: int
    ///fptr: formatfile*
    [System.Runtime.InteropServices.DllImportAttribute("coldlib.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Convert")]
    public static extern int Convert(ref formatfile fptr);

... }

【问题讨论】:

    标签: c# javascript .net com activex


    【解决方案1】:

    接口方法不能是static 或extern。这没有任何意义。特别是在 COM 中,接口总是需要从 IClassFactory::CreateInstance() 等获取的类实例。这正是 COM 的工作方式。反过来,在 C# 中,static 方法不能是接口方法的实现,即使它具有正确的参数和名称,原因相同:C# 接口引用是通过将对象(实例)引用转换为界面。

    这完全有道理!请记住,在每个接口方法调用的基础上,都有一个隐藏的(通过 C++ 和 C#)this 引用对象实例的参数。方法签名并不真正匹配,即使表面上看起来是这样。

    如果您需要将相同的方法同时公开为 COM 方法和纯 C 外部符号,则需要方法声明的两份副本:static extern 一份用于实现功能,另一份用于转发调用,声明为public int IComNativeCallsInterface.Convert(ref formatfile fptr)。如果我没记错的话(我手头没有带 VS 的计算机),通过将第二种方法声明为显式接口实现,您将能够使两个声明完全匹配名称和形式参数而不会发生冲突。

    【讨论】:

    • 完成繁重工作的一种方法是右键单击 NativeCalls 前面的接口名称并告诉 VS 为您“显式实现接口”。至少您将拥有所有声明。然后您可以填写转接电话。根据烦恼的程度,我可能会在某处(Excel、TextPad)使用宏来填写其余部分。
    • 感谢欧元的回答和解释!此外,您的提示非常适合减少时间。最佳
    猜你喜欢
    • 1970-01-01
    • 2010-12-14
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多