Подтвердить что ты не робот

AnyCPU/x86/x64 для приложения С# и его зависимость от С++/CLI

Я разработчик Windows, я использую Microsoft visual studio 2008 SP1. Моя машина для разработчиков - 64 бит.

В настоящее время я работаю над программным обеспечением, написанным на С#.exe. К сожалению, я не смог решить всю проблему исключительно на С#. Вот почему я также разработал небольшую управляемую DLL в С++/CLI. Оба проекта находятся в одном и том же решении.

My С#.exe build target - "Любой процессор". Когда моя цель сборки С++ DLL - "x86", DLL не загружается. Насколько я понял, когда я googled, причина в том, что язык С++/CLI, в отличие от других языков .NET, компилируется в собственный код, а не управляется кодом.

Я переключил цель сборки С++ DLL на x64, и теперь все работает. Тем не менее, AFAIK все перестанет работать, как только мой клиент установит мой продукт на 32-разрядную ОС. Я должен поддерживать Windows Vista и 7, как 32, так и 64-разрядные версии каждого из них.

Я не хочу возвращаться к 32 битам. Это 250 строк кода на С++ в моей DLL составляет всего 2% от моей кодовой базы. И эта DLL используется только в нескольких местах, поэтому в типичном сценарии использования она даже не загружена.

Моя DLL реализует два COM-объекта с ATL, поэтому я не могу использовать параметр /clr: safe.

Есть ли способ настроить решение и проекты, чтобы проект С# создавал версию "Любой процессор", проект С++ создает и 32-битную и 64-битную версии, а затем во время выполнения, когда управляемый .EXE запускается, он использует 32-разрядную DLL или 64-разрядную DLL в зависимости от ОС?

Или может быть какое-то лучшее решение, о котором я не знаю?

Спасибо заранее!

4b9b3361

Ответ 1

С ним нет простого способа. Если у вас есть собственный код (т.е. Ваш С++), и вам нужно поддерживать x86, тогда вам нужно скомпилировать x86 (если вы не хотите работать в мире WOW... т.е. запустить 32-разрядный код как в 32, так и в 64-битных средах). Вы можете иметь как x86, так и x64 дистрибутивы, но если вы поддерживаете 32 и 64 бит, и у вас есть собственный код или COM introp ', то вы должны иметь как 32, так и 64-битные двоичные файлы. "Любой процессор" действительно полезен только тогда, когда нет собственного кода или интерполя, тогда вы получаете этот benifit.

Ответ 2

Существует способ: иметь оболочку С# AnyCPU и проект С++ для каждой архитектуры, а также позволить оболочке С# загружать правильный проект С++ во время выполнения.

Для проекта С++ создайте одну версию для каждой архитектуры (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... */
    }
}

И в коде С++ я использую те же источники, что и я, но буду компилировать их в другое пространство имен в зависимости от архитектуры сборки:

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