C# 如何部署使用C++/CLI库
我有一个C#库,它使用AnyCPU构建,但依赖于一些C++/CLI库。我已经为x86和x64窗口编译了C++/CLI。似乎我只能向C#项目添加一个C++/CLI库的引用(否则文件会相互重写)。我认为有一个x86和x64文件夹是可能的,这两个库将分别位于其中。但当我尝试这个方法时,我会遇到运行时异常,即无法找到库C# 如何部署使用C++/CLI库,c#,.net,c++-cli,C#,.net,C++ Cli,我有一个C#库,它使用AnyCPU构建,但依赖于一些C++/CLI库。我已经为x86和x64窗口编译了C++/CLI。似乎我只能向C#项目添加一个C++/CLI库的引用(否则文件会相互重写)。我认为有一个x86和x64文件夹是可能的,这两个库将分别位于其中。但当我尝试这个方法时,我会遇到运行时异常,即无法找到库 有没有办法将x86和x64都包含在我的AnyCpu库中,以便在部署时调用应用程序可以决定是要x86还是x64 基本上你需要做以下几点: public NativeLibraryL
有没有办法将x86和x64都包含在我的AnyCpu库中,以便在部署时调用应用程序可以决定是要x86还是x64 基本上你需要做以下几点:
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
...
}
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpLibFileName);
- 检测进程体系结构(x86或x64)
- 根据架构加载正确的库
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
...
}
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpLibFileName);
使用LoadLibrary
加载本机库:
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
...
}
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpLibFileName);
//
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
///
///
///
[DllImport(“kernel32.dll”,EntryPoint=“LoadLibrary”,SetLastError=true,CharSet=CharSet.Unicode)]
公共静态外部IntPtr加载库(字符串lpLibFileName);
完整示例:
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
...
}
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpLibFileName);
您可以查看,我为其编写的.NET包装器。它是一个AnyCPU
程序集,将根据当前运行的体系结构加载x86
或x64
库
以下是您感兴趣的部分:
注意事项:
public NativeLibraryLoader(string path32, string path64)
{
if (!File.Exists(path32))
throw new FileNotFoundException("32-bit library not found.", path32);
if (!File.Exists(path64))
throw new FileNotFoundException("64-bit library not found.", path64);
string path;
switch (RuntimeInformation.ProcessArchitecture)
{
case Architecture.X86:
path = path32;
break;
case Architecture.X64:
path = path64;
break;
default:
throw new PlatformNotSupportedException();
}
...
}
/// <summary>
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx
/// </summary>
/// <param name="lpLibFileName"></param>
/// <returns></returns>
[DllImport("kernel32.dll", EntryPoint = "LoadLibrary", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string lpLibFileName);
此方法说明如何加载本机库而不是托管库
正如@Flydog57所指出的,要加载托管程序集,请使用
assembly.load
。@165plo:事实上,如果C++/CLI DLL是托管程序集(我就是这样理解这个问题的),那么您将希望使用System.Reflection.assembly.load
或它的一个朋友。但是,逻辑是正确的。但是,从“引用的程序集”的角度来看,它对您没有帮助。如果您可以控制C++/CLI代码,那么这些类是否实现了您在通用AnyCPU程序集中定义的接口,您的代码和C++/CLI代码都引用了这些接口?这样做没有本机方法吗?我发现它不是本机库发现的一部分,这有点奇怪。你说的本机方式是什么意思?上面的解决方案在方法调用时被调用,对吗?我很惊讶IL解释器没有在应用程序启动时提供这样做的方法。我可能错了,但我认为所有DLL都是在应用程序启动时加载的。是的,但正如您所指出的,您只能向程序集添加一个引用,对于它的体系结构没有区别,也就是说,它希望您为您的项目添加正确的引用。现在实施起来并不难,