c# - 适用于 C# 应用程序的 AnyCPU/x86/x64 及其 C++/CLI 依赖项

标签 c# windows 64-bit c++-cli

我是 Windows 开发人员,我使用的是 Microsoft visual studio 2008 SP1。我的开发机器是 64 位的。

我目前正在使用的软件是用 C# 编写的托管 .exe。不幸的是,我无法仅用 C# 解决整个问题。这就是为什么我还用 C++/CLI 开发了一个小型托管 DLL。这两个项目都在同一个解决方案中。

我的 C# .exe 构建目标是“任何 CPU”。当我的 C++ DLL 构建目标为“x86”时,未加载 DLL。 据我搜索时的理解,原因是 C++/CLI 语言与其他 .NET 语言不同,编译为 native 代码,而不是托管代码。

我将 C++ DLL 构建目标切换为 x64,现在一切正常。但是,据我所知,一旦我的客户将我的产品安装在 32 位操作系统上,一切都将停止工作。我必须支持 Windows Vista 和 7,每个版本的 32 位和 64 位版本。

我不想退回到 32 位。我的 DLL 中的 250 行 C++ 代码仅占我代码库的 2%。而且那个 DLL 只在几个地方使用,所以在典型的使用场景中它甚至没有被加载。

我的 DLL 使用 ATL 实现了两个 COM 对象,所以我不能使用“/clr:safe”项目设置。

有没有办法配置解决方案和项目,以便 C# 项目构建“任何 CPU”版本,C++ 项目构建 32 位和 64 位版本,然后在运行时托管时.EXE 正在启动,它使用 32 位 DLL 还是 64 位 DLL,具体取决于操作系统?

或者也许有一些我不知道的更好的解决方案?

提前致谢!

最佳答案

有一种方法:让每个架构都有一个“AnyCPU”C# 包装器和一个 C++ 项目,并让 C# 包装器在运行时加载正确的 C++ 项目。

对于 C++ 项目,针对不同的体系结构(x86、x64)创建一个版本,然后全部构建。然后在包装器中执行:

public class CppWrapper
{
    // C++ calls that will be dynamically loaded from proper architecture:
    public static readonly Func<long> MyCplusplusMethodUsableFromCsharpSpace;

    // Initialization:
    static CppWrapper()
    {
        if(Environment.Is64BitProcess)
        {
            MyCplusplusMethodUsableFromCsharpSpace = CppReferences64.MyCplusplusClass.Method;
            // Add your 64-bits entry points here...
        }
        else
        {
            MyCplusplusMethodUsableFromCsharpSpace = CppReferences32.MyCplusplusClass.Method;
            /* Initialize new 32-bits references here... */
        }
    }

    // Following classes trigger dynamic loading of the referenced C++ code
    private static class CppReferences64
    {
        public static readonly Func<long> MyCplusplusMethod = Cpp64.MyCplusplusMethod;
        /* Add any64-bits references here... */
    }
    private static class CppReferences32
    {
        public static readonly Func<long> MyCplusplusMethod = Cpp32.MyCplusplusMethod;
        /* Add any 32-bits references here... */
    }
}

在 C++ 代码中,我使用与我所说的相同的源代码,但会根据build 体系结构编译到不同的命名空间:

#ifdef _M_X64
namespace Cpp64 {
#else
namespace Cpp32 {
#endif
    public ref class MyCPlusPlusClass
    {
        public: static __int64 Method(void) { return 123; }
    };
}

关于c# - 适用于 C# 应用程序的 AnyCPU/x86/x64 及其 C++/CLI 依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2963809/

相关文章:

windows - 从 C# 调用 MsiEnumRelatedProducts 崩溃

windows - 无法通过私有(private)IP访问同一VPC中的EC2实例

ms-access - 存在32位Office时手动安装64位MS Access ODBC驱动程序

64位系统的Java AOT编译器

linux - 为什么 strace 报告我的 x64 FASM 程序在 32 位模式下运行?

c# - 覆盖枚举

c# - 如何使用WaveOut\waveIn Api录制和播放声音

c# - retrofit - 使用 retrofit 参数(字符串)作为 Controller 参数传递

c# - 可选组的正则表达式

c# - SQL 数据库 VS。多个平面文件(数以千计的小型 CSV)