【问题标题】:C#: combine DllImport with inheritance?C#:将 DllImport 与继承结合起来?
【发布时间】:2011-12-10 20:01:40
【问题描述】:

我在尝试将一些代码从 java 移植到 c# 时遇到了一些麻烦。

首先解释一下java代码背后的关键概念: 现有代码的关键概念是类导入/使用外部库中的方法。该类实现了一个接口,该接口声明了外部库中的大部分方法。好处是能够创建像

这样的实例

Interface1 实例 = new classImplementingInterface1();

我正在尝试移植实现接口并从外部库导入方法的代码。实际上我不得不将该接口转换为抽象类,因为 java 接口使用包含预定义值的字段,而 .NET 接口实际上不支持。

这可能是我的凝视点:

public abstract class abstractClassA
{
    public abstract int abstractMethodA(int parameter);
}

public class usualClass : abstractClassA
{
    [DllImort("ExternalLib.dll")]
    public static extern abstractMethodA(int parameter);
}

一个抽象类用于能够从实现该抽象类的类中创建实例,只需键入

abstractClassA instance = new usualClass();

好的,这就是我想要做的,但我发现这是行不通的,虽然我继承了一个抽象类,但我必须对我想要实现的方法使用覆盖语句

public class usualClass : abstractClassA
{
    public extern override abstractMethodA(int parameter);
}

这将无法与 DllImport 语句结合使用,因为它告诉我使用该语句的方法应同时声明:extern 和 static。添加 override 关键字来实现抽象类是不可能的,因为不能将静态成员声明为 override。所以我想我被困住了:/

但实际上我想创建一个从外部库命名入口点的类。但是我希望这个类实现一个接口/抽象类,以便能够通过键入来创建实现这个接口/抽象类的类的实例

abstractClassA instance = new usualClass();

我还使用接口尝试了这些东西(但没有烦人的静态预定义字段),我发现接口实现也不能与 DllImport 语句结合使用,编译器说命名方法是静态的,因此不能实现接口方法。这实际上是有道理的,但不是我的问题的合适解决方案。

你有过这种想法或更多想法的经验吗?

【问题讨论】:

    标签: c# .net windows visual-studio-2010 winapi


    【解决方案1】:

    正如 C# 编译器所说,方法必须static extern。幸运的是 DllImport 具有 EntryPoint 属性,它允许您在 C# 中使用不同的名称(从而避免命名冲突)。例如:

    public abstract class AbstractClassA
    {
        public abstract int AbstractMethodA(int parameter);
    }
    
    public class UsualClass : AbstractClassA
    {
        [DllImport("ExternalLib.dll", EntryPoint = "abstractMethodA")]
        static extern int AbstractMethodAImport(int parameter);
        public override int AbstractMethodA(int parameter)
        {
            return AbstractMethodAImport(parameter);
        }
    }
    

    但是,您的代码没有遵循最佳实践(另外一个烦恼,是的,这就是您在 Java 中命名事物的方式 - 但在罗马时是罗马人;请阅读 C# 命名约定 )。你真的应该按如下方式实现它:

    public abstract class AbstractClassA
    {
        public abstract int AbstractMethodA(int parameter);
    }
    
    public class UsualClass : AbstractClassA
    {
        public override int AbstractMethodA(int parameter)
        {
            return NativeMethods.AbstractMethodA(parameter);
        }
    }
    
    [SuppressUnmanagedCodeSecurity]
    internal class NativeMethods
    {
        [DllImport("ExternalLib.dll", EntryPoint = "abstractMethodA")]
        public static extern int AbstractMethodA(int parameter);
    }
    

    始终将您的外部人员留在一个班级中,您应该致电NativeMethods

    【讨论】:

    • 嗨乔纳森,感谢使用名为 NativMethods 的内部类的提示。这是个好主意,我不知道代码约定的事实。
    【解决方案2】:

    您只需要添加一个额外的间接层。您必须使用 C# 方法覆盖 AbstractMethodA,然后调用外部方法。

    public abstract class AbstractClassA
    {
        public abstract int AbstractMethodA(int parameter);
    }
    
    public class UsualClass : AbstractClassA
    {
        [DllImport("ExternalLib.dll", EntryPoint="TheFunctionName")]
        private static extern AbstractMethodAExtern(int parameter);
    
        public override int AbstractMethodA(int parameter)
        {
            return AbstractMethodAExtern(parameter);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-01-15
      • 1970-01-01
      • 2021-11-27
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-30
      • 2021-09-28
      相关资源
      最近更新 更多