Вызов управляемого кода из 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 вручную?

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

2 ответа

Решение

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

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

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

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

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

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

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

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

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

class ImportantOnceWork{
    ImportantOnceWork()
     {
         MyEntryPoint();

     }
};

int DoOnce()
{
    static ImportantOnceWork val;
}

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

Другие вопросы по тегам