L'Utilisation de C++/CLI à l'Intérieur Application C#
J'essaie d'appeler ma bibliothèque C++ à partir de mon application C# (via C++/CLI). J'ai suivi l'exemple de cette question (pour mon application). Le programme d'installation de mon application:
- Projet1: Projet C++ (j'ai compiler une DLL)
- Projet2: Projet C++ (mon CLR wrapper; le fichier d'en-tête par l'exemple ci-dessus; les références Projet1)
- Project3: Projet C# (références Project2)
Malheureusement, quand j'ai fait aller à accéder à la CLR objet wrapper dans mon application en C#, j'ai l'erreur suivante:
Le type ou le nom d'espace de noms 'YourClass'
n'a pas pu être trouvée (vous manque un
à l'aide d'une directive ou d'une assemblée
de référence?)
Je n'ai le projet de programme d'installation incorrecte, ou est-il autre chose que je devrais être à la recherche d'? (Malheureusement, je ne peux pas afficher le code de propriété raisons, mais il est très simple morceau de code et facilement suit l'exemple ci-dessus.)
Mise à jour:
Donc j'ai fait exactement ce que Chris a dit de le faire (voir la réponse ci-dessous), mais je suis encore à la réception d'un message à partir de mon application C# que "le type ou Le nom d'espace de noms 'MyProgram' n'a pas pu être trouvée (vous manque une directive using ou une référence d'assembly?). Voici un (mock-up) de mon code.
- Projet1 - C'est mon application C++. Il compile/œuvres. Je l'ai utilisé ailleurs. (J'ai une DLL de cette construction.)
- Project2 - Voici mon code pour mon wrapper.
MyWrapper.h
#pragma once
#include "myorigapp.h"
using namespace System;
namespace MyProgram
{
public ref class MyWrapper
{
private:
myorigapp* NativePtr;
public:
MyWrapper()
{
NativePtr = new myorigapp();
}
~MyWrapper()
{
delete NativePtr;
NativePtr = NULL;
}
void dostuff()
{
NativePtr->dostuff();
}
}
}
- Project3 - C'est mon application C#.
Programme.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MyProgram;
namespace Testing
{
class Program
{
static void Main(string[] args)
{
MyWrapper p = new MyWrapper();
p.dostuff();
}
}
}
Project3 références Project2 les références de Projet1. Tout ce qui appuie sans erreurs (à l'exception de l'erreur que j'ai décrit ci-dessus dans le code C# sur la using MyProgram
ligne).
vous doit poster du code, si vous ne voulez pas afficher l'original de la chose, peut-être vous pouvez extraire les éléments pertinents, de les simplifier et de modifier certains noms etc.
Mise à jour de la question avec le code et les plus d'informations.
OriginalL'auteur JasCav | 2011-04-13
Vous devez vous connecter pour publier un commentaire.
Juste, y compris l'en-tête de la pure application C++ n'est pas assez bon. Vous avez besoin d'envelopper vos objets managés avec aménagés dans Project2 (c'est à dire
public ref class YourClassDotNet
)MyManagedWrapper
généralement à faire un certain type de conversion .NET des types de données C++ natif types de données et vice versa.href="http://stackoverflow.com/questions/5655936/how-to-use-c-cli-within-c-application/5656223#5656223">à votre service, je suppose?
Manuellement assurer le natif de l'objet est correctement libérée devient compliqué rapide. Je vous suggère d'utiliser un pointeur intelligent au lieu de dupliquer cette logique dans chaque classe wrapper. en Voici un que j'ai écrit: scoped_ptr pour le C++/CLI (assurez-vous d'objet géré correctement libère appartenant à l'objet natif)
Brun Ouais c'est assez ardu, il y
Je vous remercie pour votre réponse. Cependant, je suis déjà en train de le ce. Projet1 et Projet2 faire construire correctement. Donc, je suis peut-être ne pas le faire "à l'aide" ou une référence d'assembly correctement. Pouvez-vous donner un aperçu de cette? À partir de ce que je peux dire (dans votre exemple), j'aurais une référence à Project2 de Project3, et j'aurais "à l'aide de MyManagedWrapper" en haut de la classe C# qui veut utiliser l'objet géré. Est-ce correct?
OriginalL'auteur Chris Eberle
Bon, eh bien, maintenant je me sens stupide.
Il s'avère que le problème que j'ai (que j'ai résolu il y a quelques semaines - juste eu le temps de la mise à jour de cette réponse) c'est que j'avais inclus le fichier d'en-tête (voir Chris réponse pour ça), mais je n'avais pas réellement compris le fichier CPP (qui est vide d'autres que d'inclure le fichier d'en-tête).
Une fois que je l'ai fait, la DLL compilé correctement et que je pourrais appeler des fonctions C++ (à l'aide de C++/CLI) de mon code C#.
Je vais avoir le même problème en ce moment, mais ne peut pas comprendre votre solution. Peut-être que vous pouvez expliquer? Merci
OriginalL'auteur JasCav
Chris vous a montré le moyen de créer une classe managée qui utilise le code non managé à l'intérieur. Il y a beaucoup de ce que vous pouvez faire en C# à l'aide de dangereux (c'est juste que presque personne ne le fait).
Toutefois, l'inverse est également possible: à l'aide .Types de réseau directement à partir d'un type natif/fonction.
La chose à surveiller est que tout géré pointeur doit être marqué en tant que tel. À cette fin, C++/CLI définit un type spécial de smartpointer
gcroot<T>
(imitant boost::shared_pointer ou std::auto_ptr dans un sens). Donc, pour stocker une chaîne managé à l'intérieur de votre classe C++, utilisez la commande suivante:Remarque que (si elle n'a pas été corrigé ces jours-ci), vous allez courir dans un peu de friction avec le décalage entre géré
null
et C/C++ NULL.Vous ne pouvez pas taper facilement, comme vous pouvez vous attendre:
Au lieu de cela, vous auriez à utiliser le natif de style (le smart wrapper
gcroot
gère ce)Remarque: je n'ai pas accès à une machine windows, n'importe où près de ces jours, si j'ai cité de mémoire
Ou compiler avec l' /clr drapeau
OriginalL'auteur sehe