Обнаружение ошибок при использовании взаимодействия C ++ в старом приложении MFC / Win32 - PullRequest
0 голосов
/ 30 ноября 2011

Я унаследовал старое приложение MFC / Win32 C ++, исходный код которого я не должен редактировать.

Это приложение MFC должно содержать старую библиотеку DLL MFC / Win32 C ++.Эта DLL также пытается выполнять вызовы функций через оболочку смешанного режима в управляемую C ++ / CLI DLL.Я знаю, это звучит немного запутанно, поэтому вот диаграмма того, что я имею в виду:

Old MFC/Win32 Application (NO CLR)

    ---> Hosting old MFC/Win32 DLL (NO CLR)

                 ---> Making function calls to Mixed-Mode wrapper (CLR)

                              ---> Sending function calls to C++/CLI DLL (CLR)

Моя проблема в настоящее время заключается в том, что когда я пытаюсь смонтировать объект класса оболочки C ++ / CLR, скажем, WrapperClass WC;, приложение MFC / Win32 встречает «необработанное исключение».

У меня есть ощущение, что мне может потребоваться каким-то образом разместить CLR в отдельном процессе, чтобы создать объект.Это правильная идея?Или я совершенно не в порядке?

Код компилируется во время, и это происходит только во время выполнения.

Есть идеи?

Вот пример кода, который я пытаюсь запустить:

MFC / Win32 DLL

#include "WrapperClass.h"

BOOL Test::bTest() //This function is called elsewhere within MFC/Win32 DLL
{
    DWORD dwTest;

    WrapperClass WC; //Unhandled exception here!

    return WC.FunctionToCall(dwTest); //FunctionToCall is a BOOL
}

Смешанный режимКласс Wrapper

BOOL WrapperClass::FunctionToCall(DWORD dw)
{
    GCHandle h = GCHandle::FromIntPtr(IntPtr(m_impl)); //m_impl def'd as void *
    CPPCLIClass^ CCC = safe_cast<CPPCLIClass^>(h.Target);

    return (BOOL)CCC->FunctionToCall(dw);
}

C ++ / CLI DLL

bool CPPCLIClass::FunctionToCall(UInt32 ui32)
{
    if (ui32 == 42)
    {
        return true;
    }
}

ОБНОВЛЕНИЕ: Мне удалось уговорить настоящее исключениевне программы.Сейчас я получаю исключение System.IO.FileNotFound с дополнительной информацией о том, что

An unhandled exception of type 'System.IO.FileNotFoundException' occured in 
Unknown Module.

Additional information: Could not load file or assembly 'CPPCLIProject,
Version=1.0.4351.29839, Culture=neutral, PublicKeyToken=null' or one of its 
dependencies. The system cannot find the file specified.

Означает ли это что-нибудь?Я понимаю, что он, очевидно, не может найти CPPCLIProject (Примечание: это не проект оболочки), но тогда, если я буду ссылаться на файл .lib из оболочки Смешанного режима, как я тогда не получу ошибки компоновщика?

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

Вы уверены, что реализация WrapperClass::FunctionToCall() не вызывает исключения?Похоже, вы кэшируете расположение в памяти объекта CLR, а затем пытаетесь вызвать одного из его членов.Я думаю, что CLR может свободно перемещать объекты, поэтому возможно, что вы пытаетесь использовать перемещенный объект.

Если вы измените реализацию WrapperClass::FunctionToCall() на что-то более простое (т.е. создайте CLRобъект, вызов функции-члена), вы все еще получаете такое же необработанное исключение?

ОБНОВЛЕНИЕ : Какой класс находится в CPPCLIProject - CPPCLIClass?Предполагая, что этот проект представляет C ++ / CLI DLL, похоже, он просто не может найти сборку для загрузки, когда ему нужно вызвать ваш класс.

Где находится эта сборка на диске относительно остальной частиприложение?Если ваш корневой EXE-файл неуправляемый (что звучит так, как оно есть, поскольку это MFC / Win32), то CLR просматривает каталог EXE-файла и GAC для загрузки сборок (я не думаю, что это выглядит в пути,но я не уверен в этом).

Так что, если проект CPPCLIP не находится в том же каталоге, что и EXE, это может быть вашей проблемой.

1 голос
/ 30 ноября 2011

Лучше всего

  • запускать в отладчике (добавить дополнительные библиотеки DLL с отладочной информацией в сеанс отладки)
  • разрешить разрыв для всех исключений (первый шанс)
  • отслеживание / утверждение всех кодов HRESULT
  • в общем попытайтесь перехватить
    • C ++ исключения (try/catch ...)
    • Структурированные исключения Windows (IIRC_ try / _catch, но см. MSDN )

Идея состоит в том, чтобы преобразовать «неизвестное исключение» в «известное исключение»'.

Как правило, нет необходимости размещать часть CLR вне процесса.Это то, о чем DLL смешанного режима.Опять же, если это унаследованный код, вы можете столкнуться со сложными сочетаниями зависимостей времени выполнения, которые, скажем так, могут конфликтовать.


Дальнейшие мысли:

Если я правильно понимаю, у вас есть возможность перекомпилировать всех источников (только не трогать устаревшую кодовую базу?).Если это так, убедитесь, что весь код скомпилирован для одной и той же версии (например, Service Packs) и типа (например, Static vs Dynamic / Multithread / Debug) библиотек времени выполнения.

При проверке дополнительных путей следите за потенциально конфликтующими зависимостями на

  • серверных библиотеках ATL
  • библиотек MFC (опять-таки статические против динамических / многопоточных / отладочных)ароматизаторы).
...