9
votes

En utilisant ctypes en python pour accéder aux méthodes d'un dll C #

Je voudrais mettre en œuvre le code C # dans une partie critique de mon programme python pour le rendre plus rapide. Il dit (sur la documentation Python et ce site ) que vous pouvez charger une bibliothèque de liens dynamiques (et ainsi dire les PyDocs) comme suit:

cdll.LoadLibrary ( "votre-dll-va-here.dll" ) code> p>

Ceci est la partie de mon code qui prend en charge cette fonction: p>

    [...]
    array_result = iterator.Program.ITERATE(z[0],z[1],c[0],c[1],self.iterations,M)
  File "C:\Python32\lib\ctypes\__init__.py", line 353, in __getattr__
    func = self.__getitem__(name)
  File "C:\Python32\lib\ctypes\__init__.py", line 358, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'Program' not found


5 Réponses :


8
votes

Les conseils que vous trouverez concernant l'appel de la DLL de Python à l'aide de CTYPES dépendent de la plupart du temps sur la DLL écrit en C ou C ++, pas C #. Avec C #, vous tirez dans toute la machine du CLR, et les symboles sont très susceptibles de fumer et non de ce que ctypes attendez-vous et vous obtiendrez toutes sortes de problèmes de la collecte des ordures de votre réseau de sortie.

J'ai eu un très bon succès lors de l'interface Python et du code C # à l'aide de Python pour Dot Net ( http: // pythonnet. sf.net ), vous voudrez peut-être essayer cela.

D'autre part Si vous êtes dans des performances pure, envisagez de réécrire votre code comme une extension C natif pour Python à l'aide de l'API Python / C ( http://docs.python.org/c-api/ ).


0 commentaires

1
votes

ctypes est pour chargement des bibliothèques partagées écrites en C (ou au moins des bibliothèques partagées qui sont directement exécutables par l'unité centrale de traitement et d'exporter leurs symboles et arguments de fonction suivant les conventions standard C.) DLLs C # ne sont pas DLLs "normal", mais plutôt destinés à fonctionner dans un environnement .NET.

Vos options sont:

  1. Utilisez une sorte de Python pour .NET pont.
  2. Écrivez la DLL dans C et de l'utilisation ctypes pour appeler la fonction et de gérer les conversions de données.
  3. Utilisez l'API Python / C et de créer un module Python chargeable.

    Je ne peux pas parler à l'option # 1, je n'ai pas fait. Option n ° 2 est généralement plus facile que l'option n ° 3 à ce que vous écrivez pur code C et le coller avec ctypes . Option n ° 3 offrira la meilleure performance des trois options qu'il a le plus bas frais généraux d'appel et est en cours d'exécution du code natif sur le processeur.


0 commentaires

3
votes

D'autres ont fait remarquer que C # DLL ne peut pas être traitée de la même manière que d'une DLL native.

Une option que vous avez est d'exporter votre C # fonctionnalité comme un objet COM qui peut être facilement consommé par Python.

Personnellement, je considérerais une solution de code natif, mais vous pouvez bien être trop engagé à C # pour changer de cap à ce stade.


0 commentaires

1
votes

A C # DLL est vraiment appelé une assemblée de sorte qu'il est tout à fait différente. À moins d'une raison très importante, je vous suggère d'utiliser C ++


0 commentaires

11
votes

Il est en fait assez facile. Il suffit d'utiliser NuGet pour ajouter le paquet « UnmanagedExports » à votre projet .Net. Voir https://sites.google.com/site/robertgiesecke/Home/uploads/ unmanagedexports pour plus de détails.

Vous pouvez ensuite exporter directement, sans avoir à faire une couche COM. Voici l'exemple de code C #: p>

import ctypes
a = ctypes.cdll.LoadLibrary(source)
a.add(3, 5)


1 commentaires

Si lorsque la bibliothèque ne peut pas être exécutée de Python - Petite indice - "Vous devez définir votre objectif de plate-forme sur X86, IA64 ou X64. Les assemblages AnyCPU ne peuvent pas exporter des fonctions."