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

Une solution (l'.sln)

Un projet C++ (mycppproject.vcxproj en 2010 ou le projet mycpp.vcproj en 2008) qui compile une DLL native exportant une certaine fonction (s). Dans debug ceci construit c:outputDebugmycppproject_d.dll et dans la version ceci construit c:outputReleasemycppproject.DLL.

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

tout se compile très bien.

quand je construis, je voudrais pouvoir ajouter une référence du projet csharp au projet CPP DLL afin qu'il puisse copier le fichier approprié à partir du répertoire approprié dans le répertoire binDebug dans lequel le projet csharp est intégré.

cela devrait être possible, puisque L'IDE sait tout ce qu'il y a à savoir sur l'endroit où la DLL est construite, et où L'application C# est construite.

In Visual Studio 2010:

J'ai essayé" les dépendances..."sur le projet csharp et ajouter une dépendance sur le projet mycpp, mais cela n'a pas d'effet.

J'ai essayé" ajouter une référence..."sur le projet Csharp et l'ajout d'une référence au projet cpp, mais je reçois un message d'avertissement "la version de cadre cible pour le projet" mycppproject " est plus élevée que la version de cadre cible de projet actuelle. Aimeriez-vous ajouter cette référence à votre projet de toute façon?"(Oui / Non / Annuler).

le fait de cliquer sur" Oui "produit le message d'erreur" une référence à mycppproject " n'a pas pu être ajoutée."

33
demandé sur maazza 2011-02-24 19:45:16

4 réponses

Visual Studio ne supporte pas le référencement d'un projet C++ non géré à partir d'un c# one géré, mais MSBuild supporte le référencement de n'importe quel projet à partir de n'importe quel autre projet.

, Vous pouvez ajouter manuellement une référence à votre projet en éditant le .fichier csproj à la main. Dans le fichier, Trouvez 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 le construire, la référence va amener MSBuild à construire le projet référencé en premier. La valeur ReferenceOutputAssembly indique à MSBuild de ne pas copier l'assemblage de sortie de la construction (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érencement.

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é 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 /

11
répondu Paul Turner 2017-02-28 11:27:17

vous ne pouvez pas ajouter une référence à une DLL non gérée.

à la place, vous devriez faire une tâche de post-compilation pour copier le fichier.

alternativement, vous pouvez ajouter un lien vers la DLL non gérée comme un fichier dans le projet C#, et mettre Build Action à None et Copy to Output Directory à Copy If Newer .

35
répondu SLaks 2011-02-24 16:49:11

je voudrais suivre Slaks deuxième réponse ...

[...] vous pouvez ajouter un lien vers la DLL non gérée en tant que fichier dans le projet C#, et définir L'Action de compilation à None et copier dans le répertoire de sortie pour copier Si Plus Récent.

... suivi de mon commentaire , pour faire la différence entre les compilations Debug et Release (même si c'est un peu "hackish", car il vous faut éditer manuellement le C# dossier de projet)

ouvrez le fichier csproj de votre projet C# avec un éditeur de texte et recherchez tout" YourNativeCppProject.dll" occurrences (sans le ".dll " subfix, donc si vous avez ajouté des fichiers pdb comme lien aussi, vous trouverez plus d'une occurrence), et changer le chemin D'inclusion en utilisant des macros, par exemple: Include="$(SolutionDir)$(ConfigurationName)\YourNativeCppProject.dll

PS: Si vous regardez les propriétés (F4), VS vous montre le Le chemin de débogage même si vous passez à la configuration de publication, mais si vous compilez, vous verrez que la dll copiée vers la sortie est la version de publication*

18
répondu Notoriousxl 2017-05-23 12:26:17

Add Rederences ne fonctionne que pour les assemblages .NET, les projets .net dans la même solution ou pour les composants COM ( pour lesquels un gestionnaire wrapper sera créé de toute façon... ).

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

Imaginez que DLLImport est une option runtime, le chemin dans lequel vous vous trouvez est utilisé à l'exécution pour chercher la dll, vous devez donc déployer vous-même la dll c++ et la rendre disponible pour l'application .net, généralement dans le même dossier bin.

2
répondu Davide Piras 2011-02-24 16:49:59