Unable to use Custom .dll (C#) from C++/CLI

2019-08-12 22:03发布

问题:

Thanks In advance for you time and Help.

Goal: I am trying to use my C# library within a C++ project

What I did:

  1. Created a simple .dll file with my C# project. named: ClassLibrary1.dll
  2. Created a C++ console application named: CppClr (Common Language RunTime Support Changed to: /clr)
  3. Copied ClassLibrary1.dll to the root off CppClr project

Following is my ClassLibrary1(C#) code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace ClassLibrary1
{
    public class Class1
    {
        public static void output()
        {

            String mystr; 


            mystr = "Helloo World"; // create a new string

            Console.WriteLine(mystr);
            Console.WriteLine("From C++ Managed Code!");
            Console.ReadLine();
        }
    }
}

The Following is my C++/CLI code:

#include "CppClr.h"
#using <ClassLibrary1.dll>

int main()
{
    ClassLibrary1::Class1::output();
}

Problem: The error I get when I run my C++/CLI code :

An unhandled exception of type 'System.IO.FileNotFoundException' occurred in Unknown Module.Additional information: Could not load file or assembly 'ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

回答1:

Your problem is simply an issue of your C++ executable not being able find/load the C# DLL at runtime.

There are a few different places that the .NET runtime looks to load assemblies. The simplest of these is from the same directory that your compiled application is running from. It is not enough to have ClassLibrary1.dll in the root of your C++ project - it needs to be in same directory that your project is running from.

As a quick and dirty test, you should be able to verify this by copying ClassLibrary1.dll into the C++ project's output directory. If you're running in the Debug configuration, this will probably be something like C:\Projects\CppClr\Debug\ or wherever your C++ project is. Verify that this is the directory that contains the compiled CppClr.exe file. Once you copy the DLL here and run your project, the runtime should be able to find the DLL and all should be good.

However, this could be kind of a pain if you're frequently updating your C# project, since you'll continually need to copy it to the C++ output folder every time something changes. The solution to this is to add a reference in the C++ project to your C# library.

In Visual Studio, open up your C++ project. From the solution explorer, right-click on references and select Add reference... Next, click on the Browse... button at the bottom of the dialog and browse to the location of ClassLibrary1.dll on your disk. Click on Add and then OK.

Now, whenever you build the C++ project, it will copy the ClassLibrary1.dll assembly into the project's output folder. You should also be able to remove the #using <ClassLibrary1.dll> directive from the top of your C++ file, since adding the DLL as a project reference should perform the same function.



回答2:

The msdn link shared by Chad is of the case when you want to add a dll created from C++ project.

What you need to do is to create a strong name for your C# library.

  • To create a strong name for your class library, type the following command at the Visual Studio .NET command prompt: sn.exe -k MyKeyFile.SNK

  • Copy the MyKeyFile.SNK file to your project folder.

  • Double-click the AssemblyInfo.cs file to open the file in Solution Explorer.
  • Replace the following lines of code in the AssemblyInfo.cs file

    [assembly: ComVisible(false)]
    [assembly: AssemblyDelaySign(false)]
    [assembly: AssemblyKeyFile("")]
    

with

    [assembly: ComVisible(true)] 
    [assembly: AssemblyDelaySign(false)] 
    [assembly: AssemblyKeyFile("..\\..\\MyKeyFile.SNK")]
  • Press CTRL+SHIFT+B to generate the managed DLL.
  • Now register the managed DLL for use with COM or with Native C++
  • Call the Managed DLL from Native C++ Code or using it.

The link here is close to what the OP is trying to do. https://support.microsoft.com/en-us/kb/828736



回答3:

I was able to solve this problem by specifying the absolute path of the dll file.

before:

#using "ClassLibrary1.dll"

after:

#using "C:\user\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll"

if this works for you, you need to go to Properties -> C/C++ -> General -> "Resolve #using References" and add the path here. then you can use #using "ClassLibrary1.dll" again in your could without the complete path.

Answer was found here