Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何部署使用C++/CLI库_C#_.net_C++ Cli - Fatal编程技术网

C# 如何部署使用C++/CLI库

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

我有一个C#库,它使用AnyCPU构建,但依赖于一些C++/CLI库。我已经为x86和x64窗口编译了C++/CLI。似乎我只能向C#项目添加一个C++/CLI库的引用(否则文件会相互重写)。我认为有一个x86和x64文件夹是可能的,这两个库将分别位于其中。但当我尝试这个方法时,我会遇到运行时异常,即无法找到库


有没有办法将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都是在应用程序启动时加载的。是的,但正如您所指出的,您只能向程序集添加一个引用,对于它的体系结构没有区别,也就是说,它希望您为您的项目添加正确的引用。现在实施起来并不难,