适用于C#应用程序的任何CPU / x86 / x64,并且是C ++ / CLI依赖项

我是Windows开发人员,我正在使用Microsoft Visual Studio 2008 SP1。 我的开发者机器是64位的。

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

我的C#.exe生成目标是“任何CPU”。 当我的C ++ DLL生成目标是“x86”时,DLL不加载。 据我了解,当我GOOGLE了,原因是C / CLI语言,不像其他.NET语言,编译为本地代码,而不是托pipe代码。

我将C ++ DLL构build目标切换到了x64,现在一切正常。 但是,一旦我的客户将我的产品安装在32位操作系统上,AFAIK一切都将停止工作。 我必须支持Windows Vista和7,它们都是32位和64位版本。

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

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

有没有办法configuration解决scheme和项目,以便C#项目build立“任何CPU”的版本,C + +项目build立32位和64位版本,然后在运行时,托pipe的.EXE启动时,它使用32位DLL或64位DLL取决于操作系统?

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

提前致谢!

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

有一种方法:在每个架构上都有一个“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 ++代码中,我使用了与我所说的相同的源代码,但是会根据构建体系结构将其编译为不同的名称空间:

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