C#COM库:如何为ActiveX/COM可见性修饰互操作功能行

C#COM库:如何为ActiveX/COM可见性修饰互操作功能行,c#,javascript,.net,com,activex,C#,Javascript,.net,Com,Activex,我还没有看到关于StackOverflow的答案。这是一个C#library项目,其接口定义如下(和项目设置),因此它作为COM组件可见 目标是使互操作行中的函数/方法通过COM接口可见。互操作行提供了对旧C库/dll中函数的可见性 问题通过下面NativeCalls类中Convert的互操作行显示。它包括“静态外部”。如果这些(即“static extern”)包含在类定义(如图所示)上方的接口部分中,则会出现以下错误: 修饰符“extern”对此项无效 修饰符“static”对此项无效

我还没有看到关于StackOverflow的答案。这是一个C#library项目,其接口定义如下(和项目设置),因此它作为COM组件可见

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

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

  • 修饰符“extern”对此项无效
  • 修饰符“static”对此项无效
如果我删除“extern static”,则在类中找不到接口部分中的“Convert”

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

[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);
。。。
}接口方法不能是
静态的
外部的
。这没有任何意义。特别是在COM中,接口总是需要从IClassFactory::CreateInstance()等获取的类实例。这正是COM的工作方式。反过来,在C#中,
静态
方法不能是接口方法的实现,即使它具有正确的参数和名称,原因相同:C#接口引用是通过将对象(实例)引用强制转换到接口获得的

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


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

完成繁重工作的一种方法是右键单击NativeCalls前面的接口名称,并告诉VS“显式实现接口”给你。至少你会准备好所有的声明。然后你可以填写转发呼叫。根据烦恼程度,我可能会在某个地方使用宏(Excel、TextPad)来填写其余部分。谢谢你的回答和解释!另外,你的提示对于缩短时间也很有用。最好