我是 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/