web-dev-qa-db-fra.com

Comment ajouter une référence à un projet C ++ non géré appelé par un projet C #?

Une solution (the.sln)

Un projet C++ (mycppproject.vcxproj en 2010 ou mycppproject.vcproj en 2008) qui compile une fonction native DLL exportation de certaines fonctions). Dans le débogage, cela crée c:\output\Debug\mycppproject_d.dll et dans la version cela crée c:\output\Release\mycppproject.dll.

Une application console C # (mycsharpconsole.csproj) contenant des appels PInvoke dans la DLL.

Tout compile bien.

Lorsque je crée, j'aimerais pouvoir ajouter une référence du projet csharp au projet cpp DLL afin qu'il puisse copier le fichier approprié du répertoire approprié dans le répertoire\bin\Debug répertoire dans lequel le projet csharp est intégré.

Cela devrait être possible, car le IDE sait tout ce qu'il y a à savoir sur l'endroit où le DLL est construit et où l'application C # est construite).

Dans Visual Studio 2010:

J'ai essayé "Dependencies ..." sur le projet csharp et en ajoutant une dépendance sur mycppproject, mais cela n'a aucun effet.

J'ai essayé "Ajouter une référence ..." sur le projet csharp et en ajoutant une référence au projet cpp, mais je reçois un message d'avertissement "La version de Framework cible pour le projet" mycppproject "est plus élevée que la version actuelle de Framework cible du projet . Souhaitez-vous quand même ajouter cette référence à votre projet? ' (Oui/Non/Annuler).

Un clic sur "Oui" génère le message d'erreur "Une référence à mycppproject" n'a pas pu être ajoutée. "

36
WaffleSouffle

Visual Studio ne prend pas en charge le référencement d'un projet C++ non managé à partir d'un C # one géré, mais MSBuild prend en charge le référencement de tout projet à partir de tout autre projet.

Vous pouvez ajouter manuellement une référence à votre projet en modifiant manuellement le fichier .csproj. Dans le fichier, recherchez votre ensemble existant d'éléments ProjectReference (ou ajoutez un nouveau ItemGroup si vous n'en avez pas) et ajoutez la référence suivante:

<ProjectReference Include="..\mycpproject.csproj">
  <Project>{b402782f-de0a-41fa-b364-60612a786fb2}</Project>
  <Name>mycppproject</Name>
  <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
  <OutputItemType>Content</OutputItemType>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</ProjectReference>

Lorsque vous effectuez la génération, la référence entraînera MSBuild pour générer le projet référencé en premier. La valeur ReferenceOutputAssembly indique à MSBuild de ne pas copier l'assembly de sortie de la génération (puisque le projet C++ n'en produit pas), mais les valeurs OutputItemType et CopyToOutputDirectory lui demandent de copier le contenu de sortie dans le dossier de sortie du projet de référence.

Vous pourrez voir la référence dans Visual Studio, mais vous ne pouvez pas en faire grand-chose là-bas.

Cette réponse est basée sur un problème similaire résolu par Kirill Osenkov sur son blog MSDN: https://blogs.msdn.Microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project -reference-without-referencing-the-actual-binary /

14
Paul Turner

Vous ne pouvez pas ajouter une référence à une DLL non managée.

Au lieu de cela, vous devez effectuer une tâche de post-génération pour copier le fichier.

Vous pouvez également ajouter un lien vers le fichier non managé DLL en tant que fichier dans le projet C # et définir Build Action à None et Copy to Output Directory à Copy If Newer.

36
SLaks

Je suivrais deuxième réponse de Slaks ...

[...] vous pouvez ajouter un lien vers le DLL DLL non géré sous la forme d'un fichier dans le projet C #, et définir la valeur Build Action sur None et Copy to Output Répertoire à copier si plus récent.

... suivi de mon commentaire , pour différencier les versions de débogage et de version (même si c'est un peu "hackish", car cela vous oblige à éditer manuellement le fichier de projet C #)

ouvrez le fichier csproj de votre projet C # avec un éditeur de texte et recherchez toutes les occurrences "YourNativeCppProject.dll" (sans le sous-correctif ".dll", donc si vous avez ajouté des fichiers pdb comme lien également, vous trouverez plus d'une occurrence) et modifiez le chemin d'inclusion à l'aide de macros, par exemple: Include = "$ (SolutionDir) $ (ConfigurationName)\YourNativeCppProject.dll

PS: si vous regardez les propriétés (F4), VS vous montre le chemin du débogage même si vous basculez vers la configuration Release, mais si vous compilez, vous verrez que la DLL copiée en sortie est la version release *

18
Notoriousxl

Ajouter des références ne fonctionne que pour les assemblys .NET, les projets .net dans la même solution ou pour les composants COM (pour lesquels un wrapper de gestionnaire sera créé de toute façon ...).

le fait que dans votre code C # vous accédez à la DLL C++ avec DLLImport ne pas signifie que Visual Studio saura d'où et où la DLL externe doit être copiée.

Imaginez que DLLImport est une option d'exécution, le chemin que vous y insérez est utilisé lors de l'exécution pour rechercher la DLL, vous devez donc déployer la DLL c ++ vous-même et la rendre disponible pour l'application .net, généralement dans le même dossier bin.

2
Davide Piras