适用于Chrome的NPAPI插件无法通过NP_Initialize
NPAPI Plugin for Chrome doesn't get past NP_Initialize
我一直在尝试为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>
标签的空白页面,我得到一条消息说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"
和I链接到.DLL中:
g++.exe -Wl,--subsystem,windows -o "npplugin.dll" -s -shared main.o resource.o -lcomctl32 -lws2_32 -luxtheme -lgdi32 -lshell32 -lshlwapi
函数表之间的大小根据浏览器和浏览器版本的不同而不同。
根据硬编译库头文件检查大小:
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使用的结构中。
我建议使用某种形式的日志记录而不是消息框;你有没有试过移除被击中的消息框,看看你是否能走得更远?Chrome启动插件的进程,所以它会期望这些入口点及时完成,否则它可能会杀死插件。
另外,——plugin-startup-dialog选项在某些情况下可能很有用,这样你就可以确定插件何时启动;此外,如果您想附加调试器并查看是否可以通过这种方式找到更多信息,它可能会很有用。仅供参考。我也会尝试在firefox中加载它;有时在另一个浏览器中加载插件会得到不同的信息。如果它在其中一个中有效,而在另一个中无效,这也可以告诉你一些东西。
mm尝试更改NP_GetEntryPoints()
pFuncs->newp = &NPP_New;
pFuncs->destroy = &NPP_Destroy;
(…)
pFuncs->newp = NPP_New;
pFuncs->destroy = NPP_Destroy;
- 什么等于 np.linalg.solve(A, B) 的 Python 在特征C++
- 这个循环是什么意思:for(j,0,np)
- Initialize std::array of std::array
- 当我们在 C++ 中说"initialize the object"时,它实际上意味着什么?
- (也许是NP-Hard)求一个集合的子集总数,使得每个子集在与其所有元素相乘时的值都大于X
- np.arange与C++iota的比较,iota更慢
- 如何使用 <numpy/arrayobject.h> 在 c++ 中将数据从 np.array 获取到 std::vector?
- 在C 中实现Python np.fromstring()
- 调用对象中的"initialize"函数时调用其成员函数之一
- 有没有办法像python:np.concatenate([x,y,z],axis=1)中那样沿着列连接三个二维向量C++
- 如果用户在Ruby with Rice中重新定义initialize(),则避免C++代码中的Segfault
- 文件写入权限在Firebreath NP插件中被拒绝
- 无法用C++编写相同的 Java 代码"cannot initialize class member here"因为错误
- 在资源管理器左窗格上两次调用Windows 7外壳扩展dll Initialize方法
- 反对"initialize()"方法而不是构造函数的参数
- 将numpy指针(dtype=np.bool)传递给C++
- 无法更改调用接口时的initialize数组
- IAudioClient::Initialize方法的未解析外部符号.API公司
- C++ initialize map of pairs
- 未定义符号SystemRuntimeMacOSX::Initialize和SystemRuntimeMacOSX::Te