C #: combinez DllImport avec l’inheritance?

Certains problèmes surgissent pour moi en essayant de porter un code de Java vers c #.

Au début, quelques explications sur le concept clé du code Java: Le concept clé du code existant est une classe qui importe / utilise des méthodes dans une bibliothèque externe. Cette classe implémente une interface qui déclare la plupart des méthodes de la bibliothèque externe. L’avantage est la possibilité de créer des instances comme

Interface1 instance = new classImplementingInterface1 ();

J’essaie de porter le code qui implémente une interface et importe les méthodes d’une bibliothèque externe. En fait, je devais traduire cette interface en une classe abstraite car l’interface java utilise des champs contenant des valeurs prédéfinies, qui ne sont pas sockets en charge dans les interfaces .NET.

C’est peut-être mon sharepoint départ:

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

Une classe abstraite permet de créer des instances à partir de classes implémentant cette classe abstraite en tapant simplement

 abstractClassA instance = new usualClass(); 

Ok, thats ce que je veux faire, mais j’ai compris que cela ne fonctionnera pas, alors que je hérite de la forme d’une classe abstraite, je devrai utiliser l’instruction override pour les méthodes que je veux implémenter comme

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

Cela ne marchera pas avec l’instruction DllImport car cela me dit que les méthodes utilisant cette instruction doivent déclarer à la fois: extern et static. L’ajout du mot clé override pour implémenter la classe abstraite n’est pas possible car un membre statique ne peut pas être déclaré en tant que remplacement. Donc je suppose que je suis piégé comment: /

Mais en fait, je veux créer une classe nommant le point d’entrée à partir d’une bibliothèque externe. Mais je veux que cette classe implémente une classe interface / abstract pour pouvoir créer des instances de classes implémentant cette interface / classe abstraite simplement en tapant

 abstractClassA instance = new usualClass(); 

J’ai aussi essayé ce truc en utilisant une interface (mais sans gêner les champs statiques prédéfinis) et j’ai découvert que l’implémentation d’interface ne fonctionne pas combinée avec l’instruction DllImport aussi, le compilateur dit que la méthode nommée est statique et ne peut donc pas implémenter une interface méthode. Cela a du sens, mais ce n’est pas une solution adaptée à mon problème.

Avez-vous des expériences avec cela ou d’autres idées?

Comme le compilateur C # dit que la méthode DOIT être static extern . Heureusement, DllImport a la propriété EntryPoint qui vous permet d’utiliser un nom différent en C # (évitant ainsi les conflits de noms). Par exemple:

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

Cependant, votre code ne suit pas les meilleures pratiques ( bêtise supplémentaire, oui, c’est comme ça que vous nommez les choses en Java – mais quand à Rome, soyez romain, lisez les conventions de nommage C # ). Vous devez vraiment le mettre en œuvre comme suit:

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

Gardez toujours vos extern dans une seule classe, que vous devriez appeler NativeMethods .

Vous devez simplement append une couche supplémentaire d’indirection. Vous devez remplacer abstractMethodA par une méthode C # qui à son tour appelle la méthode externe.

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