web-dev-qa-db-fra.com

Appel de code C # à partir de C ++

Je dois pouvoir invoquer des fonctions C # arbitraires à partir de C++. http://www.infoq.com/articles/in-process-Java-net-integration suggère d'utiliser ICLRRuntimeHost :: ExecuteInDefaultAppDomain () mais cela ne me permet que d'appeler des méthodes ayant ce format: int method(string arg)

Quelle est la meilleure façon d'invoquer des fonctions C # arbitraires?

39
Gili

Compilez votre code C++ avec l'indicateur / clr. Avec cela, vous pouvez appeler n'importe quel code .NET avec une relative facilité.

Par exemple:

#include <tchar.h>
#include <stdio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    System::DateTime now = System::DateTime::Now;
    printf("%d:%d:%d\n", now.Hour, now.Minute, now.Second);

    return 0;
}

Est-ce que cela compte comme "C++"? Eh bien, ce n'est évidemment pas C++ standard ...

25
Ðаn
48
cdiggins

Si vous ne vous souciez pas si votre programme C++ (ou une partie de celui-ci) est compilé avec/clr, vous pouvez utiliser C++/CLI pour simplement appeler n'importe quel code .NET (tant que vous y ajoutez une référence). Essayez cet article .

EDIT: Voici n joli tutoriel

L'autre voie consiste à rendre votre code C # exposé en tant que COM.

6
Filip Frącz

Le moyen le plus simple consiste à utiliser COM interop.

3
laktak

Comme approche alternative, vous pouvez utiliser Lua pour instancier les objets CLR, exécuter et renvoyer les résultats.

1
David Robbins

Vous pouvez utiliser un wrapper appelable COM autour de votre code C # compilé dans une DLL.

1
Dan Vinton

Voir DllExport .

IOW: L'exact opposé du fonctionnement de DllImport.

https://github.com/3F/DllExport

Il prend en charge Windows, avec une prise en charge multiplateforme en cours.

Code C # (que nous appelons depuis C++):

[DllExport]
public static int _add(int a, int b)
{
    return a + b;
}

[DllExport]
public static bool saySomething()
{
    DialogResult dlgres = MessageBox.Show(
        "Hello from managed environment !",
        ".NET clr",
        MessageBoxButtons.OKCancel
    );

    return dlgres == DialogResult.OK;
}

Code C++ (qui appelle le code C # précédent):

typedef int(__cdecl *_add)(int a, int b);
typedef bool(__cdecl *saySomething)();

auto pAdd = (_add)GetProcAddress(lib, "_add");
int c = pAdd(5, 7);

auto pSaySomething = (saySomething)GetProcAddress(lib, "saySomething");
bool dlgres = pSaySomething();

Et une vidéo YouTube avec une démo sur Managed & Unmanaged; PInvoke; [Conari vs DllExport] . Pour être honnête, la documentation est parfaite, mais ne vous découragez pas: les vidéos YouTube sont excellentes.

Ce projet est inspiré d'un autre projet de Robert Giesecke qui a 220 000 téléchargements sur NuGet .

Fait amusant: certaines bibliothèques Python l'ont utilisé pour implémenter des fonctionnalités dans un mélange de C++ et C #.

Et enfin, merci Robert Giesecke et Denis Kuzmin, brillant, brillant travail!

1
Contango

De Microsoft: Écrivez un hôte .NET Core personnalisé pour contrôler le runtime .NET à partir de votre code natif .

IOW: Appelez C # à partir de C++ sur Windows et Linux.

Il y a exemple de code sur GitHub .

Cet exemple de code est multiplateforme, il permet au code C # dans .NET Core d'être appelé à partir de n'importe quelle application C++ sur Linux et Windows.

En toute honnêteté, cette solution semble être assez compliquée par rapport à l'autre réponse DllExport. Le code C++ fait beaucoup de travail pour analyser les ressources et les points d'entrée, etc. Un argument pour cette réponse pourrait être qu'il est multiplateforme. Cependant, l'autre réponse DllExport est également multiplateforme et beaucoup plus simple à utiliser.

0
Contango