windows 用于 C# 应用程序的 AnyCPU/x86/x64 及其 C++/CLI 依赖项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2963809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AnyCPU/x86/x64 for C# application and it's C++/CLI dependency
提问by Soonts
I'm Windows developer, I'm using Microsoft visual studio 2008 SP1. My developer machine is 64 bit.
我是 Windows 开发人员,我使用的是 Microsoft Visual Studio 2008 SP1。我的开发机器是 64 位的。
The software I'm currently working on is managed .exe written in C#. Unfortunately, I was unable to solve the whole problem solely in C#. That's why I also developed a small managed DLL in C++/CLI. Both projects are in the same solution.
我目前正在开发的软件是用 C# 编写的托管 .exe。不幸的是,我无法仅用 C# 解决整个问题。这就是为什么我还在 C++/CLI 中开发了一个小的托管 DLL。两个项目都在同一个解决方案中。
My C# .exe build target is "Any CPU". When my C++ DLL build target is "x86", the DLL is not loaded. As far as I understood when I googled, the reason is C++/CLI language, unlike other .NET languages, compiles to the native code, not managed code.
我的 C# .exe 构建目标是“任何 CPU”。当我的 C++ DLL 构建目标是“x86”时,未加载 DLL。据我在谷歌搜索时理解,原因是 C++/CLI 语言,与其他 .NET 语言不同,编译为本机代码,而不是托管代码。
I switched the C++ DLL build target to x64, and everything works now. However, AFAIK everything will stop working as soon as my client will install my product on a 32-bit OS. I have to support Windows Vista and 7, both 32 and 64 bit versions of each of them.
我将 C++ DLL 构建目标切换到 x64,现在一切正常。但是,一旦我的客户将我的产品安装在 32 位操作系统上,AFAIK 一切都会停止工作。我必须支持 Windows Vista 和 7,它们分别是 32 位和 64 位版本。
I don't want to fall back to 32 bits. That 250 lines of C++ code in my DLL is only 2% of my codebase. And that DLL is only used in several places, so in the typical usage scenario it's not even loaded.
我不想回退到 32 位。我的 DLL 中的 250 行 C++ 代码仅占我代码库的 2%。而且那个 DLL 只在几个地方使用,所以在典型的使用场景中它甚至没有加载。
My DLL implements two COM objects with ATL, so I can't use "/clr:safe" project setting.
我的 DLL 用 ATL 实现了两个 COM 对象,所以我不能使用“ /clr:safe”项目设置。
Is there way to configure the solution and the projects so that C# project builds "Any CPU" version, the C++ project builds both32 bit and 64 bit versions, then in the runtime when the managed .EXE is starting up, it uses either 32-bit DLL or 64-bit DLL depending on the OS?
有没有办法来配置解决方案和项目,使C#项目建立“任何CPU”的版本来,C ++项目建立两个32位和64位版本,然后在运行时管理.EXE启动时,它使用的是32 -bit DLL 或 64 位 DLL 取决于操作系统?
Or maybe there's some better solution I'm not aware of?
或者也许有一些我不知道的更好的解决方案?
Thanks in advance!
提前致谢!
采纳答案by David B Heise
There is no easy way around it. If you have native code (i.e. your C++) and you need to support x86, then you have to compile x86 (unless you want to work in WOW world...ie. running 32 bit code in both 32 and 64 bit envrionments). You canhave both an x86 and x64 distributions, but if you're supporting both 32 and 64 bit, and you have native code or COM introp' then you have tohave both 32 and 64 bit binaries. "Any CPU" only really is useful when there is no native code or interop, then you get that benifit.
没有简单的方法可以解决。如果您有本机代码(即您的 C++)并且您需要支持 x86,那么您必须编译 x86(除非您想在 WOW 世界中工作......即在 32 位和 64 位环境中运行 32 位代码)。您可以同时拥有 x86 和 x64 发行版,但如果您同时支持 32 位和 64 位,并且您拥有本机代码或 COM introp',那么您必须同时拥有 32 位和 64 位二进制文件。“任何 CPU”只有在没有本机代码或互操作时才有用,然后你就会得到好处。
回答by gatopeich
There is a way: to have an "AnyCPU" C# wrapper and a C++ project per architecture, and let the C# wrapper load the right C++ project at run time.
有一种方法:每个体系结构都有一个“AnyCPU”C# 包装器和一个 C++ 项目,并让 C# 包装器在运行时加载正确的 C++ 项目。
For the C++ project, create one version per different architecture (x86, x64), and build them all. Then in the wrapper do:
对于 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... */
}
}
And in the C++ code, I use the same sources as I said, but will compile to different namespace depending on the buildarchitecture:
在 C++ 代码中,我使用与我所说的相同的源代码,但会根据构建架构编译到不同的命名空间:
#ifdef _M_X64
namespace Cpp64 {
#else
namespace Cpp32 {
#endif
public ref class MyCPlusPlusClass
{
public: static __int64 Method(void) { return 123; }
};
}