GetProcAddress не работает, даже если имя правильно искажено

У меня есть следующий код в .dll:

namespace MyNamespace
{
    extern "C" __declspec(dllexport) int __stdcall GetOptionID(unsigned long num)
    {
        return 0;
    }
}

Это скомпилировано на Visual C++ 2010, поэтому у меня также есть файл .def, содержащий GetOptionID. Я вижу, что функция экспортируется и искажается как _GetOptionID@4, используя dumpbin /exports:

File Type: DLL

  Section contains the following exports for MyLibrary.dll

    00000000 characteristics
    53D269CB time date stamp Fri Jul 25 15:29:31 2014
        0.00 version
           1 ordinal base
          13 number of functions
          13 number of names

    ordinal hint RVA      name

          1    0 0006F030 CmdOne = _CmdOne@16
          2    1 0006F510 CmdUnimpl = _CmdUnimpl@16
          3    2 0006EBB0 DefineThing = _DefineThing@32
          4    3 0006E0C0 GetOptionID = _GetOptionID@4

В отдельном исполняемом файле я пытаюсь проверить наличие GetOptionID:

HINSTANCE hinst = LoadLibraryEx(file_name, NULL, DONT_RESOLVE_DLL_REFERENCES);
if(!hinst)
    return FALSE;

FARPROC_IDI lp = (FARPROC_IDI) GetProcAddress(hinst, "_GetOptionID@4");
auto e = GetLastError();

Запустив этот код в отладчике, я вижу, что:

  • LoadLibraryEx удается - у меня есть действующий вид hinst
  • GetProcAddress терпит неудачу - lp становится 0x00000000
  • GetLastError возвращает 127

Я вижу, что функция была экспортирована, и я вижу, что ее имя соответствует точке входа, которую я ищу. Почему GetProcAddress терпит неудачу?


person Chowlett    schedule 25.07.2014    source источник
comment
Вы неправильно читаете вывод dumpbin. Экспортируемое имя находится слева от знака равенства.   -  person Raymond Chen    schedule 25.07.2014


Ответы (1)


А, сам решил. Определение функции в файле .def приводит к тому, что ее имя полностью искажается, а это означает, что правильной целью для GetProcAddress было просто GetOptionID.

Однако, поскольку у меня есть другие библиотеки .dll, которые проходят ту же проверку и действительно являются _GetOptionID@4, фактическим решением было удалить GetOptionID из файла .def.

person Chowlett    schedule 25.07.2014