【发布时间】:2011-10-22 17:46:16
【问题描述】:
我一直在尝试为使用 NPAPI 插件的 Chrome 编写扩展程序。我正在使用 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> 标签的空白页面,我收到一条消息说NP_GetEntryPoints,然后是一条说NP_Initialize,然后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"
然后我用 :
链接到一个 .DLLg++.exe -Wl,--subsystem,windows -o "npplugin.dll" -s -shared main.o resource.o -lcomctl32 -lws2_32 -luxtheme -lgdi32 -lshell32 -lshlwapi
【问题讨论】:
-
有一点,虽然我怀疑这是问题所在,但这些都应该是 &NPP_New 等;在这种情况下,& 运算符在某些编译器中是可选的,但为了正确起见,您应该拥有它。
-
@Taxilian 谢谢,我忘记了。不幸的是,它对崩溃没有帮助:(。
-
你导出的函数可能需要是__stdcall。
-
@Luke 他们是,它在
npfunctions.h的声明中设置。我在正确导出它们时遇到了一些麻烦,但我已经解决了这个问题...... -
是吗?我很确定您需要在函数声明和定义中包含(相同的)调用约定。由于您的定义不包括它并且(大概)编译器没有抱怨它,我不确定。据我所知,npfunctions.h 似乎是一个标准头文件,它只定义函数签名而没有实际声明任何函数(除非你的函数被修改),所以那里指定的任何调用约定都不适用于你的函数。
标签: c++ windows google-chrome-extension npapi