2010-07-14 7 views
5

J'ai un code hérité implémenté en C (pas C++). Je voudrais être en mesure d'appeler quelques méthodes dans ce code C à partir de mon code C# (sur Windows). Quelle serait la meilleure approche pour l'interface entre les deux langues? Veuillez noter que la méthode en C n'est pas apatride. Nous devons appeler deux méthodes:parler à C à partir de C#

  1. initialisation() => ceci initialise la structure de données et charge les données des fichiers dans la mémoire. Cette méthode sera appelée une fois.
  2. ComputeQuelque chose (paramètres) => il y aura plusieurs appels de C# à cette méthode.

Note: Ces deux méthodes appellent en fait plusieurs autres méthodes, mais ce ne sont que les deux méthodes que nous voudrions exposer à C# (le code est assez compliqué, c'est la raison pour laquelle nous ne voulons pas au port à C#)

J'ai été en mesure d'importer le code c dans Visual Studio et capable de compiler le code avec succès. Je sais que nous pouvons probablement implémenter le code C en tant que service Windows mais je cherche une solution qui nous permette d'appeler directement la méthode C à partir de C#. Tout pointeur est très apprécié! (COM interop lié à ce que je cherche à faire?)

+0

pourquoi ne pas mettre en œuvre vos méthodes sur C#? – Luiscencio

+0

Quelle est la sortie compilée de votre code C? Si c'est un .dll et supporte COM, vous devriez simplement être en mesure de faire un "ajouter une référence" à partir de Visual Studio et parcourir le fichier dll. – Nate

+1

Si vous ne l'avez pas déjà fait, encapsuler vos fonctions dans une classe COM et utiliser .NET/COM interop semble trop de travail/trop de travail. Je voudrais simplement mettre ces deux fonctions C dans une DLL et y accéder avec P/Invoke, comme suggéré par Jason Evans. – stakx

Répondre

10

On dirait que vous pouvez utiliser P/Invoke pour cela. Consultez ce site pour obtenir des conseils:

http://www.pinvoke.net/

Aussi, essayez la recherche SO des conseils sur P/Invoke et Google pour

C# PInvoke appelant code c

Je n'ai pas tous les exemples techniques à portée de main, mais j'ai écrit un certain code .NET qui a appelé l'API Win32 via P/Invoke. La partie délicate consiste à obtenir les signatures de méthode correctes lors du passage des paramètres. This pourrait vous aider.

+0

Merci pour la réponse! Savez-vous si P/Invoke fonctionnerait pour ma situation où les appels de méthode sont stateful? (besoin d'appeler initialize pour charger les données avant d'appeler une autre méthode) Les variables globales restent-elles en mémoire pour l'appel de méthode suivant? – mwong

+0

Main sur le coeur, je ne sais pas. Cependant, puisque le code C doit être chargé dans l'espace d'adresse du code .NET et rester résident (pas chargé dynamiquement à chaque fois), je m'attendrais à ce que les valeurs du code C restent les mêmes. J'ai peur que ce soit quelque chose dont vous aurez besoin d'expérimenter. :(Dites-nous ce que vous découvrez, et si ma logique est totalement fausse! –

2

La version récente de Visual Studio vous permet d'écrire du code C++ qui peut appeler des fonctions non sécurisées tout en restant en interface avec le code géré CLR. Ils appellent cela "Implicit PInvoke", ou "C++/CLR". Consultez l'article MSDN "Using C++ Interop" pour en savoir plus.

Le code managé ne peut pas être appelé directement, vous avez donc besoin de fonctions wrapper pour gérer les problèmes de gestion de la mémoire et traduire entre les objets .NET et les structures de données de votre application. À partir du lien ci-dessus, consultez la section sur "Comment: Envelopper la classe native pour une utilisation par C#."

1

Voici une solution. La solution permet d'appeler la fonction C# de C en décorant votre fonction avec l'attribut [DllExport] (opposé de P/Invoke DllImport).

https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports

Code C#

class Test 
{ 
    [DllExport("add", CallingConvention = CallingConvention.StdCall)] 
    public static int Add(int left, int right) 
    { 
     return left + right; 
    } 
} 

code C

int main() 
{ 
     int z = add(5,10); 
     printf("The solution is found!!! Z is %i",z); 
     return 0; 
}