C#:将DllImport与继承结合起来?
我在尝试将一些代码从java移植到c#时遇到了一些麻烦 首先,对java代码背后的关键概念进行一些解释: 现有代码的关键概念是在外部库中导入/使用方法的类。此类实现了一个接口,该接口声明了外部库中的大多数方法。其好处是能够创建如下实例 Interface1实例=新的classImplementingInterface1() 我正在尝试移植实现接口并从外部库导入方法的代码。实际上,我必须将该接口转换为一个抽象类,因为java接口使用了包含预定义值的字段,这在.NET接口中是不受支持的 这可能是我的出发点:C#:将DllImport与继承结合起来?,c#,.net,windows,visual-studio-2010,winapi,C#,.net,Windows,Visual Studio 2010,Winapi,我在尝试将一些代码从java移植到c#时遇到了一些麻烦 首先,对java代码背后的关键概念进行一些解释: 现有代码的关键概念是在外部库中导入/使用方法的类。此类实现了一个接口,该接口声明了外部库中的大多数方法。其好处是能够创建如下实例 Interface1实例=新的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();
abstractClassA instance = new usualClass();
好的,这就是我想要做的,但我发现这行不通,当我从一个抽象类继承时,我必须对我想要实现的方法使用override语句,比如
public class usualClass : abstractClassA
{
public extern override abstractMethodA(int parameter);
}
这不能与DllImport语句结合使用,因为它告诉我使用该语句的方法应该同时声明:extern和static。无法添加override关键字来实现抽象类,因为静态成员不能声明为override。所以我想我被一些方法迷住了:/
但实际上我想创建一个类,从外部库命名入口点。但是我希望这个类实现一个接口/抽象类,能够通过键入
abstractClassA instance = new usualClass();
abstractClassA instance = new usualClass();
我还使用一个接口(但没有恼人的静态预定义字段)尝试了这种方法,我发现接口实现也不能与DllImport语句结合使用,编译器说指定的方法是静态的,因此不能实现接口方法。这实际上是有道理的,但并不是解决我问题的合适办法
你有这样或更进一步的想法的经验吗?你只需要添加一个额外的间接层。您必须用一个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);
}
}
正如C#编译器所说,该方法必须是静态外部
。幸运的是,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
Hi Jonathan,感谢使用名为NativMethods的内部类的tipp。这是个好主意,我不知道代码约定的事实。