Почему экспортированные функции не имеют правильного имени в DLL? - PullRequest
1 голос
/ 16 января 2012

Я пытаюсь сделать небольшой тест-плагин, используя NPAPI для Firefox. Это мой код:

/*  File: npp_test.cpp
    Copyright (c) 2012 by Niklas Rosenstein

    Testing the NPAPI interface. */

// - Includes & Preprocessors --------------------------------------------------
// - -------- - ------------- --------------------------------------------------

#define DEBUG

#ifdef DEBUG
#   include <iostream>
    using namespace std;
#   include <windows.h>
#endif // DEBUG

#include <stdint.h>

#include <npapi.h>
#include <npfunctions.h>
#include <npruntime.h>

#define DLLEXPORT extern __declspec(dllexport)

// - NPAPI Calls ---------------------------------------------------------------
// - ----- ----- ---------------------------------------------------------------

NPError NP_New(NPMIMEType pluginType, NPP npp, uint16_t mode, int16_t argc,
               char* argn[], char* argv[], NPSavedData* saved);

// - Entrypoints ----------------------
// - ----------- ----------------------

NPError NP_GetEntryPoints(NPPluginFuncs* pFuncs) {
#   ifdef DEBUG
    cout << "NP_GetEntryPoints\n";
#   endif // DEBUG

    // Initialize plugin-functions
    pFuncs->newp = NP_New;

    return NPERR_NO_ERROR;
}

NPError NP_Initialize(NPNetscapeFuncs* npFuncs) {
#   ifdef DEBUG
    cout << "NP_Initialize\n";
    MessageBox(NULL, "NP_Initialize", "Plugin-message", 0);
#   endif // DEBUG
    return NPERR_NO_ERROR;
}

NPError NP_Shutdown() {
#   ifdef DEBUG
    cout << "NP_Shutdown\n";
#   endif // DEBUG
    return NPERR_NO_ERROR;
}

// - Plugin Execution -----------------
// - ------ --------- -----------------

NPError NP_New(NPMIMEType   pluginType,
               NPP          npp,
               uint16_t     mode,
               int16_t      argc,
               char*        argn[],
               char*        argv[],
               NPSavedData* saved) {
#   ifdef DEBUG
    cout << "NP_New\n";
#   endif

    if (!npp)
        return NPERR_INVALID_INSTANCE_ERROR;

    return NPERR_NO_ERROR;
}

Я компилирую код, используя g ++ 4.4.1

g++ npp_test.cpp -I"D:\include\xulrunner" -shared -Wall -Wextra -o "npp_test.dll"

Компилируется нормально, но при просмотре содержимого DLL с использованием DLL Expat имена не соответствуют ожидаемым:

==================================================
Function Name     : _get_output_format
Address           : 0x6889c658
Relative Address  : 0x0001c658
Ordinal           : 5 (0x5)
Filename          : npp_test.dll
Type              : Exported Function
Full Path         : C:\Users\niklas\Desktop\npp_test.dll
==================================================

==================================================
Function Name     : _Z6NP_NewPcP4_NPPtsPS_S2_P12_NPSavedData
Address           : 0x68881270
Relative Address  : 0x00001270
Ordinal           : 4 (0x4)
Filename          : npp_test.dll
Type              : Exported Function
Full Path         : C:\Users\niklas\Desktop\npp_test.dll
==================================================

==================================================
Function Name     : NP_GetEntryPoints@4
Address           : 0x688811d8
Relative Address  : 0x000011d8
Ordinal           : 1 (0x1)
Filename          : npp_test.dll
Type              : Exported Function
Full Path         : C:\Users\niklas\Desktop\npp_test.dll
==================================================

==================================================
Function Name     : NP_Initialize@4
Address           : 0x68881205
Relative Address  : 0x00001205
Ordinal           : 2 (0x2)
Filename          : npp_test.dll
Type              : Exported Function
Full Path         : C:\Users\niklas\Desktop\npp_test.dll
==================================================

==================================================
Function Name     : NP_Shutdown@0
Address           : 0x6888124f
Relative Address  : 0x0000124f
Ordinal           : 3 (0x3)
Filename          : npp_test.dll
Type              : Exported Function
Full Path         : C:\Users\niklas\Desktop\npp_test.dll
==================================================

Разве они не должны называться как в источнике? Например, при «экспатриации» java-dll для firefox имена подходят. Использование DLLEXPORT в качестве

#define DLLEXPORT __declspec(dllexport)

тоже не работает. Но это как минимум «удаляет» функции _get_output_format и _Z6NP_NewPcP4_NPPtsPS_S2_P12_NPSavedData от экспорта, , независимо от того, экспортируются они , если не используется DLLEXPORT .

Почему имена экспортируемых функций имеют дополнительный суффикс @4 / @0? Я предполагаю, что число после @ указывает количество байтов, которые функция принимает в качестве аргументов, но при экспорте это не должно содержаться в имени, верно?

Ответы [ 4 ]

3 голосов
/ 16 января 2012

@ (stack_size_of_params) является украшением имени для функций stdcall extern "C". Я более знаком с инструментами Microsoft, но я считаю, что вам нужно будет использовать файл .def для экспорта недекорированных имен для функций, использующих stdcall.

Редактировать: Websearch предлагает, чтобы опция командной строки --kill-at для инструментов GNU могла избежать необходимости в утомительных файлах .def.

1 голос
/ 16 января 2012

С GCC NP_EXPORT уже заботится о видимости символа, например ::10000

extern "C" NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs);

Это работает только для Unixes, поэтому для GCC в Windows вам придется установить видимости самостоятельно .

В Windows / VC ++ вы также должны указать экспорт в .def файле, как указано:

NP_GetEntryPoints   @1
NP_Initialize       @2
NP_Shutdown         @3
1 голос
/ 16 января 2012

Если вы хотите контролировать экспортируемые имена функций, используйте раздел EXPORTS в файле определения компоновщика (* .def), а не __declspec(dllexport).

1 голос
/ 16 января 2012

Это C ++, поэтому имена искажаются, если вы не объявляете их также с помощью extern "C"

...