Вызов управляемого кода из DLLMain

Я пишу неуправляемые DLL (с ​​C ++ и WinAPI), но я хочу использовать некоторые методы C #, поэтому я создал оболочку с использованием C ++ / CLI.

Но проблема в том, что неуправляемая DLL будет «внедрена» (LoadLibrary), и я застрял здесь, не зная, как я могу вызывать функции Wrapper.

Неуправляемый код:

#include <Windows.h>

//the function I want to call
__declspec(dllexport) void SimpleTest(int *p);

extern "C" __declspec(dllexport) void MyEntryPoint()
{
int* test;
SimpleTest(test);
}

BOOL WINAPI DllMain(/*DllMain parameters*/)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
MyEntryPoint();
break;
}

return TRUE;
}

Оболочка (C ++ / CLI):

__declspec(dllexport) void SimpleTest(int* p)
{
*p = 1;
}

Я не знаю, что здесь происходит. Среда .NET не была загружена? DLL-архиватор не был загружен? (Я перебрал модули, а обертки там не было).

Нужно ли инициализировать CLR вручную?

Я читал о блокировке загрузчика, но я не уверен, что это проблема здесь.

1

Решение

От документации до DllMain:

Существуют значительные ограничения на то, что вы можете безопасно делать в точке входа DLL. См. Общие рекомендации для конкретных API-интерфейсов Windows, которые небезопасны для вызова в DllMain. Если вам нужно что-то кроме самой простой инициализации, сделайте это в функции инициализации для DLL. Вы можете требовать, чтобы приложения вызывали функцию инициализации после запуска DllMain и до того, как они вызовут любые другие функции в DLL.

Вызов в управляемый код — одна из тех вещей, которые вы не можете сделать!

Стандартный способ справиться с этим — создать поток в DllMainразрешенное действие и вызов управляемого кода из этого потока.

3

Другие решения

Dlls и общие объекты имеют проблемную жизнь в стандартах C / C ++.

Операционная система загружает DLL, вызывает DllMain, инициализирует глобальные переменные, затем загружает зависимые DLL.

Это означает, что
а) во время создания DllMain / global у вас есть блокировка загрузчика
б) зависимые DLL не могут быть загружены.

Это означает, что CLR может быть неактивен (не инициализирован) и может зависать, если требуется блокировка загрузчика.

Откладывание на потом — лучшее решение.

class ImportantOnceWork{
ImportantOnceWork()
{
MyEntryPoint();

}
};

int DoOnce()
{
static ImportantOnceWork val;
}

Затем вызовите DoOnce (); в каждой точке крючка.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector