用于C#应用程序的AnyCPU / x86 / x64及其C ++ / CLI依赖性

时间:2010-06-03 06:47:05

标签: 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。 据我所知,当我用Google搜索时,原因是C ++ / CLI语言与其他.NET语言不同,编译为本机代码,而不是托管代码。

我将C ++ DLL构建目标切换为x64,现在一切正常。但是,一旦我的客户端将我的产品安装在32位操作系统上,AFAIK的所有内容都将停止工作。我必须支持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,具体取决于操作系统?

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

提前致谢!

2 个答案:

答案 0 :(得分:10)

有一种方法:每个架构都有一个“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; }
    };
}

答案 1 :(得分:7)

没有简单的方法。如果您有本机代码(即您的C ++)并且您需要支持x86,那么您必须编译x86(除非您想在WOW世界中工作...即在32位和64位环境中运行32位代码)。你可以同时拥有x86和x64发行版,但如果你支持32位和64位,并且你有本机代码或COM introp'那么你必须 32位和64位二进制文​​件。 “没有任何CPU”只有在没有本机代码或互操作时才真正有用,那么你就能获得好处。