C#:将 DllImport 与继承结合起来?

发布于 2024-12-11 07:15:55 字数 1306 浏览 0 评论 0原文

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

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

Interface1 instance = 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();

“好吧,这就是我想做的,但我发现这行不通,而我继承”形成一个抽象类,我必须对我想要实现的方法使用 override 语句,就像

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

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

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

abstractClassA instance = new usualClass();

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

您有这方面的经验或进一步的想法吗?

Some trouble comes up for me while trying to port some code from java to c#.

At first, some explanation of the key concept behind the java code:
The key concept of the existing code is a class importing/using methods in an external library. This class implements an interface, which declares most of the methods from the external library. The benefit is the ability to create instances like

Interface1 instance = new classImplementingInterface1();

I'm trying to port code which implements an interface and imports methods from a external library. Actually I had to translate that interface to an abstract class because the java interface makes use of fields containing pre defined values, which is not supported in .NET interfaces acutally.

That may be my staring point:

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

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

An abstract class is used to be able to create instances from classes implementing that abstract class just by typing

abstractClassA instance = new usualClass();

Ok, thats what I want to do, but I figured out that this won't work, while I inherit form an abstract class, i'll have to use the override statement for methods I want to implement like

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

This will not work combined with the DllImport statement because it's telling me that methods using that statement shall declare both: extern and static. Adding the override keyword to implement the abstract class is not possible because a static member can't be declared as override. So I guess I'm traped some how :/

But actually I want to create a class naming the entry point from an external library. But I want this class to implement an interface / abstract class to have the ability to create instances of classes implementing this interface / abstract class just by typing

abstractClassA instance = new usualClass();

I also tried this stuff using an interface (but without annoying static pre defined fields) and I found out that interface implementation does not work combined with the DllImport statement too, the compiler says that the named method is static and therefore can not implement an interface method. That actually makes sense, but is no suiteable solution to my problem.

Do you have experiences with that or furhter ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅紫色的梦幻 2024-12-18 07:15:55

正如 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

As the C# compiler says the method MUST be static extern. Fortunately DllImport has the EntryPoint property which lets you use a different name in C# (thus avoiding naming conflicts). For example:

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);
    }
}

However, your code does not follow best practices (additional pet peeve, yes, that's how you name things in Java - but when in Rome be a Roman; please read up on the C# naming conventions). You should really implement it as follows:

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);
}

Always keep your externs in a single class, that you should call NativeMethods.

花期渐远 2024-12-18 07:15:55

您只需要添加一个额外的间接层。您必须使用 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);
    }
}

You simply need to add an extra layer of indirection. You have to override AbstractMethodA with a C# method that in turn calls the external method.

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);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文