вызов родного указателя на функцию в c ++ / cli - PullRequest
1 голос
/ 24 сентября 2010

У меня есть встроенная функция внутри управляемой (c ++ / cli) библиотеки смешанного режима, которая вызывает отдельную встроенную библиотеку DLL.

Вот встроенная функция, которая инициализирует некоторые указатели на функции с помощью окон GetProcAdress:

//in header
static HMODULE hDll;
static void (*MYDLL_Func1)(void*);
static void (*MYDLL_Func2)(void);

int BeginDll()
{
    if (!hDll) {
        hDll= LoadLibraryHelper("mydll.dll");
        if (hDll) {
            MYDLL_Func1 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func1");
            MYDLL_Func2 = (LPVOID)GetProcAddress(hDll, "MYDLL_Func2");

            if (!MYDLL_Func1||
                !MYDLL_Func2)
            {
                FreeLibrary(hDll); hDll= NULL;
            } else {
                Log("were good to go");
            }
        }
    }
    return (hDll!= NULL);
}

Теперь я хочу написать функцию-обертку, которая будет вызывать этот указатель на функцию, но при этом я получаю «AccessViolationException»

public ref struct Wrapper sealed abstract
{
    void ManagedFunc(IntPtr hwnd)
    {
        if (BeginDll())
        {
            MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));
            MYDLL_Func2();
        }
    }
}

Я не предполагаю, что могу вызвать указатель на функциюв коде c ++ / cli мне просто интересно найти правильный способ сделать это.Если я добавляю файл заголовка api dll и вызываю функции неявно, я сталкиваюсь с проблемой, что, если нативный помощник dll не находится в каталоге с управляемым dll, приложение бомб после первого вызова.( "AccessViolationException")

Ответы [ 2 ]

1 голос
/ 01 октября 2010

По какой-то причине правильный ответ был опубликован Хансом Пассатом, но он больше недоступен, если кто-то захочет узнать, как это было исправлено, я подведу итог:

статические объявления указателей на функции приводили к тому, что каждый исходный файл имел свою собственную копию, поэтому они стали следующими в файле объявлений

extern void (*MYDLL_Func1)(void*);

и в исходном файле

void (*MYDLL_Func1)(void*);

он также говорит, чтобы изменить соглашение о вызовах на _stdcall, но это в файле .C, но _cdecl компилируется просто отлично.

Однако в итоге я вернулся к включению заголовочного файла DLL и неявному вызову функций. По какой-то причине с этим решением я получал переполнение буфера в моем клиенте C # при работе вне отладчика. Видя, что проблема не существует при попытке отладки, я вернулся к другому решению. Полагаю, мне просто нужно быть осторожным, чтобы не включать DLL в мою управляемую DLL и клиент.

1 голос
/ 27 сентября 2010
MYDLL_Func1(reinterpret_cast<HWND>(hwnd.ToPointer));

должно быть

MYDLL_Func1(hwnd.ToPointer());

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...