Плагин NPAPI для Chrome не проходит NP_Initialize - PullRequest
2 голосов
/ 22 октября 2011

Я пытался написать расширение для Chrome, которое использует плагин NPAPI.Я использую MINGW для его компиляции.Первоначально я изо всех сил пытался заставить Chrome загрузить плагин, но теперь у меня другая проблема.

Мне удалось заставить Chrome вызывать NP_GetEntryPoints и NP_Initialize, но сразу после этого происходит сбой.Вот мой код до сих пор ...

main.cpp :

#include <iostream>
#include <cstdlib>
#include <Windows.h>
#include <npapi.h>
#include <npfunctions.h>
#define Exported extern "C" __declspec(dllexport)

NPNetscapeFuncs NPNFuncs;

Exported NPError NP_Initialize(NPNetscapeFuncs* pFuncs) {

    if (pFuncs == NULL)
        return NPERR_INVALID_FUNCTABLE_ERROR;

    if (HIBYTE(pFuncs->version) > NP_VERSION_MAJOR)
        return NPERR_INCOMPATIBLE_VERSION_ERROR;

    if (pFuncs->size < sizeof(NPNetscapeFuncs))
        return NPERR_INVALID_FUNCTABLE_ERROR;

    // Save functions
    NPNFuncs.size             = pFuncs->size;
    NPNFuncs.version          = pFuncs->version;
    NPNFuncs.geturlnotify     = pFuncs->geturlnotify;
    NPNFuncs.geturl           = pFuncs->geturl;
    NPNFuncs.posturlnotify    = pFuncs->posturlnotify;
    NPNFuncs.posturl          = pFuncs->posturl;
    NPNFuncs.requestread      = pFuncs->requestread;
    NPNFuncs.newstream        = pFuncs->newstream;
    NPNFuncs.write            = pFuncs->write;
    NPNFuncs.destroystream    = pFuncs->destroystream;
    NPNFuncs.status           = pFuncs->status;
    NPNFuncs.uagent           = pFuncs->uagent;
    NPNFuncs.memalloc         = pFuncs->memalloc;
    NPNFuncs.memfree          = pFuncs->memfree;
    NPNFuncs.memflush         = pFuncs->memflush;
    NPNFuncs.reloadplugins    = pFuncs->reloadplugins;
    NPNFuncs.getJavaEnv       = pFuncs->getJavaEnv;
    NPNFuncs.getJavaPeer      = pFuncs->getJavaPeer;
    NPNFuncs.getvalue         = pFuncs->getvalue;
    NPNFuncs.setvalue         = pFuncs->setvalue;
    NPNFuncs.invalidaterect   = pFuncs->invalidaterect;
    NPNFuncs.invalidateregion = pFuncs->invalidateregion;
    NPNFuncs.forceredraw      = pFuncs->forceredraw;*/

    // Success
    MessageBoxA(0, "NP_Initialize", "Log", 0);
    return NPERR_NO_ERROR;

}

Exported void NP_Shutdown() {

    MessageBoxA(0, "NP_Shutdown", "Log", 0);

}

    /* Entry points */
    NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData) {

        MessageBoxA(0, "NPP_New", "Log", 0);
        return NPERR_NO_ERROR;

    }

    NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {

        MessageBoxA(0, "NPP_GetValue", "Log", 0);
        return NPERR_NO_ERROR;

    }

    /*** Omitted... All the other functions are here, with just a MessageBox call in them ***/

Exported NPError NP_GetEntryPoints(NPPluginFuncs* pFuncs) {

    if (pFuncs == NULL)
        return NPERR_INVALID_FUNCTABLE_ERROR;

    if (pFuncs->size < sizeof(NPPluginFuncs))
        return NPERR_INVALID_FUNCTABLE_ERROR;

    pFuncs->size                = sizeof(NPPluginFuncs);
    pFuncs->version             = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
    pFuncs->newp                = &NPP_New;
    pFuncs->destroy             = &NPP_Destroy;
    pFuncs->setwindow           = &NPP_SetWindow;
    pFuncs->newstream           = &NPP_NewStream;
    pFuncs->destroystream       = &NPP_DestroyStream;
    pFuncs->asfile              = &NPP_StreamAsFile;
    pFuncs->writeready          = &NPP_WriteReady;
    pFuncs->write               = &NPP_Write;
    pFuncs->print               = &NPP_Print;
    pFuncs->event               = &NPP_HandleEvent;
    pFuncs->urlnotify           = &NPP_URLNotify;
    pFuncs->getvalue            = &NPP_GetValue;
    pFuncs->setvalue            = &NPP_SetValue;
    pFuncs->javaClass           = NULL;
    pFuncs->gotfocus            = &NPP_GotFocus;
    pFuncs->lostfocus           = &NPP_LostFocus;
    pFuncs->urlredirectnotify   = &NPP_URLRedirectNotify;
    pFuncs->clearsitedata       = &NPP_ClearSiteData;
    pFuncs->getsiteswithdata    = &NPP_GetSitesWithData;

    MessageBoxA(0, "NP_GetEntryPoints", "Log", 0);
    return NPERR_NO_ERROR;

}

Я добавил вызов MessageBox для каждой функции, чтобы я мог видеть, правильные ли функцииназываются.Когда я запускаю свою тестовую страницу, которая является пустой страницей с тегом <embed>, я получаю сообщение «1011 *», затем одно «1012 *», затем в Chrome появляется панель с сообщением о сбое моего плагина.Я думаю, что проблема в моем NP_GetEntryPoints, но я просто не вижу этого ... Есть ли что-то, что я делаю не так или забываю делать?

Я компилирую с:

g++.exe -DWIN32 -D_WIN32 -D_WINDOWS -D_WIN32_WINNT=0x0600 -D_WIN32_IE=0x0600 -D_UNICODE -DUNICODE -static-libgcc -static-libstdc++ -c "main.cpp" -o main.o

и

windres.exe "resource.rc" "resource.o"

и я связываю в .DLL с:

g++.exe -Wl,--subsystem,windows -o "npplugin.dll" -s -shared main.o resource.o -lcomctl32 -lws2_32 -luxtheme -lgdi32 -lshell32 -lshlwapi

Ответы [ 3 ]

5 голосов
/ 19 ноября 2012

Размер между таблицами функций различается для разных браузеров и версий.

Вы проверяете размер по заголовкам вашей жестко скомпилированной библиотеки:

if (pFuncs->size < sizeof(NPNetscapeFuncs))
    return NPERR_INVALID_FUNCTABLE_ERROR;

Это может быть проблемой. Например, самый последний (на момент написания Gecko xulrunner SDK содержит структуру размером 84 байта:

typedef struct _NPPluginFuncs {
  uint16_t size;
  uint16_t version;
  NPP_NewProcPtr newp;
  NPP_DestroyProcPtr destroy;
  NPP_SetWindowProcPtr setwindow;
  NPP_NewStreamProcPtr newstream;
  NPP_DestroyStreamProcPtr destroystream;
  NPP_StreamAsFileProcPtr asfile;
  NPP_WriteReadyProcPtr writeready;
  NPP_WriteProcPtr write;
  NPP_PrintProcPtr print;
  NPP_HandleEventProcPtr event;
  NPP_URLNotifyProcPtr urlnotify;
  void* javaClass;
  NPP_GetValueProcPtr getvalue;
  NPP_SetValueProcPtr setvalue;
  NPP_GotFocusPtr gotfocus;
  NPP_LostFocusPtr lostfocus;
  NPP_URLRedirectNotifyPtr urlredirectnotify;
  NPP_ClearSiteDataPtr clearsitedata;
  NPP_GetSitesWithDataPtr getsiteswithdata;
  NPP_DidCompositePtr didComposite;
} NPPluginFuncs;

Chrome отправляет 80-байтовую структуру.

Так что я думаю, что последний указатель на функцию не входит в структуру, используемую chrome.

1 голос
/ 22 октября 2011

Я бы порекомендовал использовать какую-либо форму регистрации, а не ящики сообщений;Вы пытались удалить сообщения, которые получают удар и посмотреть, если вы сделаете это дальше?Chrome запускает плагин вне процесса, поэтому он будет ожидать своевременного завершения этих точек входа, иначе он может убить плагин.

Кроме того, опция --plugin-startup-dialog может бытьполезно в некоторых случаях просто так, чтобы вы могли точно знать, когда плагин запускается;Кроме того, это может быть полезно, если вы хотите подключить отладчик и посмотреть, сможете ли вы найти больше информации таким образом.Просто к вашему сведению.Я также попытался бы загрузить это в firefox;иногда загрузка плагина в другом браузере дает вам другую информацию.Если это работает в одном, а не в другом, это тоже может вам что-то сказать.

0 голосов
/ 23 ноября 2011

мм попробуйте изменить на NP_GetEntryPoints()

  pFuncs->newp                = &NPP_New;
  pFuncs->destroy             = &NPP_Destroy;

(...)

на

  pFuncs->newp                = NPP_New;
  pFuncs->destroy             = NPP_Destroy;
...