2010-01-18 3 views
6

J'utilise Visual Studio 2008 pour créer une solution avec deux projets: une console C# App et une DLL C++. Je veux que l'application appelle une fonction de la DLL en utilisant P/Invoke. Par conséquent, j'essaie d'ajouter la DLL comme référence à l'application C#. Mais lorsque j'essaie la commande Ajouter une référence, Visual Studio ne me laisse pas le faire sauf si j'ai défini la propriété/clr sur la DLL (sous Propriétés de configuration: Général). Maintenant, je pensais que P/Invoke pouvait gérer les dlls win32. En effet, si je construis ma DLL sans/clr et que je la copie à la main dans bin/Debug, l'application fonctionne bien. Alors, pourquoi/clr est-il nécessaire d'ajouter la DLL comme référence? Et si VS ne me laisse pas l'ajouter, existe-t-il une solution de contournement (propre) pour que mon application trouve la DLL?Ajouter une référence d'une application C# à une DLL compilée sans/clr?

Je vois que quelqu'un a eu un problème similaire ici (mais avec une DLL tierce): Unable to add a DLL Reference to VS 2008 La réponse qu'il a eu était de construire un wrapper. Mais ce n'est pas vraiment nécessaire, car l'application peut très bien utiliser la DLL; c'est juste l'étape Add Reference qui ne fonctionne pas. Et d'ailleurs, le code de wrapper n'aura-t-il pas besoin d'une référence à la DLL, soulevant le même problème qu'avant? Je voudrais vraiment une réponse qui n'implique pas d'écrire un emballage du tout. Lors de l'utilisation de PInvoke sur une DLL C++, il n'est pas nécessaire d'ajouter une référence.

Répondre

7

Pourquoi ne pas simplement ajouter une étape de post-construction pour copier votre DLL non managée dans votre répertoire de projet? Vous n'avez pas besoin d'une "référence" pour pouvoir faire référence à une DLL non gérée, et il semble que le seul problème que vous rencontrez est dû au fait que le fichier n'est pas automatiquement copié dans le chemin de recherche.

+0

J'ai écrit une étape de pré-construction pour l'application C# en utilisant cette ligne de commande: Copier "$ (SolutionDir) Debug \ MathDll.dll" "$ (TargetDir)". Hélas, je souhaite que la fonctionnalité "Ajouter une référence" fonctionne, car maintenant je dois maintenir cela, et je suppose que cela sera différent pour les versions de versions ... Je ne vois pas vraiment pourquoi "Ajouter une référence" ne devrait pas gérer ce genre de chose. –

+3

Je viens de trouver une façon un peu plus propre de le faire. Plutôt que d'utiliser une commande DOS pré/post-build, j'ai ajouté la dll au projet C# en tant que "Item existant". Ensuite, sous ses propriétés, j'ai défini "Copier dans le répertoire de sortie" sur "Copier si plus récent". (Son "Build Action" est "Content.") Cela me semble encore un peu hackish, mais au moins il corrige le problème Debug-vs-Release, et c'est un peu plus facile à repérer. –

+0

Oups - J'ai réalisé que ma deuxième solution de contournement ne résout pas le problème Debug-vs-Release, parce que j'ai référencé la DLL du dossier Déboguer. D'un autre côté, la première solution de contournement peut gérer ce problème en modifiant la commande pour copier "$ (SolutionDir) $ (Configuration) \ MathDll.dll" "$ (TargetDir)". –

6

Les références sont nécessaires uniquement lorsque vous appelez du code managé dans une autre DLL. Placez simplement la DLL C++ dans le même répertoire et ajoutez son nom à l'attribut DllImport

0

En théorie, vous pouvez ajouter la DLL C++ en tant que ressource liée à votre C# -DLL. Cela ferait. NET copier votre C++ - DLL partout où il copie le C# -DLL même dans le GAC. signifie théoriquement qu'il ya quelques inconvénients:

  • Vous pouvez demander au compilateur C# (csc.exe) via les options de ligne de commande pour ajouter la ressource liée mais je ne trouve un moyen de le faire via .csproj ou même Visual Studio
  • Si le C# -DLL contient des contrôles utilisateur WinForms et que vous souhaitez l'utiliser dans le concepteur, il ne fonctionnera pas car Winforms-Designer copie le C# -DLL dans un emplacement temporaire où il le charge mais ignore la ressource liée .
  • Je ne sais pas si cela fonctionne si vous mettez votre C# -DLL dans le GAC (oui la C++-DLL serait aussi une ressource, mais je ne sais pas si elle est trouvée lors de l'exécution de votre C# - DLL)

donc, si aucun des ci-dessus est un no-go pour vous que vous pouvez appeler csc.exe les éléments suivants:

csc.exe ... /linkresource:cpp.dll 

Hope this peut aider!

0

Correction d'un problème similaire en procédant comme suit:

  1. Sur toutes les machines de développement , a ajouté le chemin de dll-s en question variable PATH enviromental. De cette façon, tous les développeurs peuvent déboguer tous les exécutables qui ont une référence à l'assembly avec des DLL non managées, sans avoir besoin d'écrire un script de post-construction pour chaque exécutable.Pour la production, la tâche msbuild de nuit génère tout dans un seul dossier et les DLL non managées qui sont marquées comme "Content/Always copy" sont automatiquement incluses dans la construction de cet assembly dont elles font partie. .

Questions connexes