Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm Windows developer, I'm using Microsoft visual studio 2008 SP1. My developer machine is 64 bit.

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.

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.

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.

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.

My DLL implements two COM objects with ATL, so I can't use "/clr:safe" project setting.

Is there way to configure the solution and the projects so that C# project builds "Any CPU" version, the C++ project builds both 32 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?

Or maybe there's some better solution I'm not aware of?

Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
782 views
Welcome To Ask or Share your Answers For Others

1 Answer

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.

For the C++ project, create one version per different architecture (x86, x64), and build them all. Then in the wrapper do:

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 build architecture:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...