C#: combine DllImport with inheritance?

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?


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 .


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
{
    [DllImort("ExternalLib.dll", EntryPoint="TheFunctionName")]
    private static extern abstractMethodAextern(int parameter);

    public override int abstractMethodA(int parameter)
    {
        return abstractMethodAextern(parameter);
    }
}
链接地址: http://www.djcxy.com/p/39436.html

上一篇: 如何使用逆变参数将通用接口转换为基本类型?

下一篇: C#:结合DllImport与继承?