无法从 C++/CLI 使用自定义 .dll (C#)
Unable to use Custom .dll (C#) from C++/CLI
提前感谢您的宝贵时间和帮助。
目标:我正在尝试在 C++ 项目中使用我的 C# 库
我做了什么:
- 用我的 C# 项目创建了一个简单的 .dll 文件。命名:ClassLibrary1.dll
- 创建了一个名为:CppClr 的 C++ 控制台应用程序(公共语言运行时支持更改为:/clr)
- 已将 ClassLibrary1.dll 复制到 CppClr 项目的根目录下
以下是我的 ClassLibrary1(C#) 代码:
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();
}
}
}
以下是我的C++/CLI代码:
#include "CppClr.h"
#using <ClassLibrary1.dll>
int main()
{
ClassLibrary1::Class1::output();
}
问题: 当我 运行 我的 C++/CLI 代码时出现的错误:
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.
Chad 分享的 msdn link 就是当你想添加从 C++ 项目创建的 dll 时的情况。
您需要做的是为您的 C# 库创建一个强名称。
要为您的 class 库创建强名称,请在 Visual Studio .NET 命令提示符下键入以下命令:
sn.exe -k MyKeyFile.SNK
将 MyKeyFile.SNK 文件复制到您的项目文件夹。
- Double-click AssemblyInfo.cs 文件在解决方案资源管理器中打开文件。
替换AssemblyInfo.cs文件中的以下代码行
[assembly: ComVisible(false)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
和
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("..\..\MyKeyFile.SNK")]
- 按 CTRL+SHIFT+B 生成托管 DLL。
- 现在注册托管 DLL 以用于 COM 或本机 C++
- 从本机 C++ 代码调用托管 DLL 或使用它。
这里的 link 接近 OP 试图做的事情。
https://support.microsoft.com/en-us/kb/828736
您的问题只是您的 C++ 可执行文件在 运行 时无法 find/load C# DLL 的问题。
.NET 运行time 会在几个不同的地方加载程序集。其中最简单的是来自您编译的应用程序 运行ning 所在的同一目录。在您的 C++ 项目的根目录中包含 ClassLibrary1.dll
是不够的 - 它需要与您的项目 运行 位于同一目录中。
作为一个快速而肮脏的测试,您应该能够通过将 ClassLibrary1.dll
复制到 C++ 项目的输出目录来验证这一点。如果您在调试配置中 运行ning,这可能类似于 C:\Projects\CppClr\Debug\
或您的 C++ 项目所在的任何位置。确认这是包含已编译 CppClr.exe
文件的目录。一旦你在这里复制 DLL 和 运行 你的项目,运行时间应该能够找到 DLL,一切都应该是好的。
但是,如果您经常更新 C# 项目,这可能会有点麻烦,因为每次更改时您都需要不断地将其复制到 C++ 输出文件夹。解决方法是在 C++ 项目中添加一个 reference 到你的 C# 库中。
在 Visual Studio 中,打开您的 C++ 项目。在解决方案资源管理器中,right-click 在 引用 和 select 添加引用... 接下来,单击 Browse... 对话框底部的按钮,然后浏览到磁盘上 ClassLibrary1.dll
的位置。单击 添加,然后单击 确定。
现在,无论何时构建 C++ 项目,它都会将 ClassLibrary1.dll
程序集复制到项目的输出文件夹中。您还应该能够从 C++ 文件的顶部删除 #using <ClassLibrary1.dll>
指令,因为将 DLL 添加为项目引用应该执行相同的功能。
我通过指定dll文件的绝对路径解决了这个问题。
之前:
#using "ClassLibrary1.dll"
之后:
#using "C:\user\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll"
如果这对您有用,您需要转到 属性 -> C/C++ -> 常规 -> "Resolve #using References" 并添加路径这里。那么你可以在没有完整路径的情况下再次使用 #using "ClassLibrary1.dll"
。
已找到答案here
提前感谢您的宝贵时间和帮助。
目标:我正在尝试在 C++ 项目中使用我的 C# 库
我做了什么:
- 用我的 C# 项目创建了一个简单的 .dll 文件。命名:ClassLibrary1.dll
- 创建了一个名为:CppClr 的 C++ 控制台应用程序(公共语言运行时支持更改为:/clr)
- 已将 ClassLibrary1.dll 复制到 CppClr 项目的根目录下
以下是我的 ClassLibrary1(C#) 代码:
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();
}
}
}
以下是我的C++/CLI代码:
#include "CppClr.h"
#using <ClassLibrary1.dll>
int main()
{
ClassLibrary1::Class1::output();
}
问题: 当我 运行 我的 C++/CLI 代码时出现的错误:
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.
Chad 分享的 msdn link 就是当你想添加从 C++ 项目创建的 dll 时的情况。
您需要做的是为您的 C# 库创建一个强名称。
要为您的 class 库创建强名称,请在 Visual Studio .NET 命令提示符下键入以下命令: sn.exe -k MyKeyFile.SNK
将 MyKeyFile.SNK 文件复制到您的项目文件夹。
- Double-click AssemblyInfo.cs 文件在解决方案资源管理器中打开文件。
替换AssemblyInfo.cs文件中的以下代码行
[assembly: ComVisible(false)] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")]
和
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("..\..\MyKeyFile.SNK")]
- 按 CTRL+SHIFT+B 生成托管 DLL。
- 现在注册托管 DLL 以用于 COM 或本机 C++
- 从本机 C++ 代码调用托管 DLL 或使用它。
这里的 link 接近 OP 试图做的事情。 https://support.microsoft.com/en-us/kb/828736
您的问题只是您的 C++ 可执行文件在 运行 时无法 find/load C# DLL 的问题。
.NET 运行time 会在几个不同的地方加载程序集。其中最简单的是来自您编译的应用程序 运行ning 所在的同一目录。在您的 C++ 项目的根目录中包含 ClassLibrary1.dll
是不够的 - 它需要与您的项目 运行 位于同一目录中。
作为一个快速而肮脏的测试,您应该能够通过将 ClassLibrary1.dll
复制到 C++ 项目的输出目录来验证这一点。如果您在调试配置中 运行ning,这可能类似于 C:\Projects\CppClr\Debug\
或您的 C++ 项目所在的任何位置。确认这是包含已编译 CppClr.exe
文件的目录。一旦你在这里复制 DLL 和 运行 你的项目,运行时间应该能够找到 DLL,一切都应该是好的。
但是,如果您经常更新 C# 项目,这可能会有点麻烦,因为每次更改时您都需要不断地将其复制到 C++ 输出文件夹。解决方法是在 C++ 项目中添加一个 reference 到你的 C# 库中。
在 Visual Studio 中,打开您的 C++ 项目。在解决方案资源管理器中,right-click 在 引用 和 select 添加引用... 接下来,单击 Browse... 对话框底部的按钮,然后浏览到磁盘上 ClassLibrary1.dll
的位置。单击 添加,然后单击 确定。
现在,无论何时构建 C++ 项目,它都会将 ClassLibrary1.dll
程序集复制到项目的输出文件夹中。您还应该能够从 C++ 文件的顶部删除 #using <ClassLibrary1.dll>
指令,因为将 DLL 添加为项目引用应该执行相同的功能。
我通过指定dll文件的绝对路径解决了这个问题。
之前:
#using "ClassLibrary1.dll"
之后:
#using "C:\user\ClassLibrary1\ClassLibrary1\bin\Debug\ClassLibrary1.dll"
如果这对您有用,您需要转到 属性 -> C/C++ -> 常规 -> "Resolve #using References" 并添加路径这里。那么你可以在没有完整路径的情况下再次使用 #using "ClassLibrary1.dll"
。
已找到答案here