Импортировать NPAPI DLL в приложение C++

Я должен импортировать NPAPI DLL в приложении C++ для моего проекта. Я следую превосходному учебнику: http://colonelpanic.net/2009/03/building-a-firefox-plugin-part-one/

Однако у меня есть некоторые проблемы с доступом к методам DLL. (Примечание: в браузере DLL полностью функциональна). После вызова основных функций: NP_GetEntryPoints и NP_Initialize и получения ScriptableNPObject, вызов методов не возвращает значения без ошибок. Имена свойств или методов такие же, как в javascript в браузере (функциональный случай).

Для информации имена свойств и методов и mime-type были заменены в этом примере.

У кого-нибудь есть идея вызывать методы dll, имитируя то, что делает браузер?

Вот часть основной программы:

if (hDLL == 0)
{
    std::cout << "DLL failed to load!" << std::endl;
}
else
{
    std::cout << "DLL loaded!" << std::endl;

    //WRAP NP_GETENTRYPOINTS FUNCTION:
    _GetEntryPointsFunc = (GetEntryPointsFunc)GetProcAddress(hDLL, "NP_GetEntryPoints");
    if (_GetEntryPointsFunc)
    {
        std::cout << "Get NP_GetEntryPoints Function!" << std::endl;
        status = _GetEntryPointsFunc(pFuncs);

    }

    //WRAP NP_INITIALIZE FUNCTION:
    _InitializeFunc = (InitializeFunc)GetProcAddress(hDLL, "NP_Initialize");
    if (_InitializeFunc)
    {   
        std::cout << "Get NP_Initialize Function!" << std::endl;
        status = _InitializeFunc(&sBrowserFuncs);
    }


    int32_t       mode = NP_EMBED; 
    int32_t       argc = 7;
    static const char mimetype[] = "application/x-mime_type_of_my_plugin";

    char * argn[] = {"param1", "param2", "param3", "param4", "param5", "param6", "param7"};
    char * argv[] = { "value1", "value2", "value3", "value4", "value5", "value6", "value7" };



    NPObject np_object;
    uint16_t size;
    char* descritpionString;
    char* nameString;

  instance = &(plugin_instance.mNPP);
    status = pFuncs->newp((char*)mimetype, instance, (uint16_t)mode, argc, argn, argv, &saved);
    status = pFuncs->version; //OK  
    status = pFuncs->getvalue(instance,NPPVpluginDescriptionString,&descritpionString); //OK
    status = pFuncs->getvalue(instance,NPPVpluginNameString,&nameString); //OK

    status = pFuncs->getvalue(instance,NPPVpluginScriptableNPObject,&np_object); //ISSUE STARTS HERE

    std::cin.get();

}

Вот моя функция create_object, вызываемая после получения сценария NPObject с функцией getvalue:

NPObject* _createobject(NPP npp, NPClass* aClass)
{

if (!npp) {
    return nullptr;
}

if (!aClass) {
    return nullptr;
}

NPObject *npobj;

if (aClass->allocate) {
    npobj = aClass->allocate(npp, aClass);
} else {
    npobj = (NPObject *)malloc(sizeof(NPObject));
}

if (npobj) {
    npobj->_class = aClass;
    npobj->referenceCount = 1;

    //TEST:
            NPError status;
    NPString url;
    NPVariant result;
    NPVariant variant;
    NPIdentifier property = "existing_property";
    NPIdentifier *arrayId;
    uint32_t count = 2;

    const char *str = "https://test_url.com";
    url.UTF8Characters = str;//;
    url.UTF8Length = 20;

    variant.type = NPVariantType_String;
    variant.value.stringValue = url;
    NPVariant args[] = { variant };

    status = 1; //GENERIC ERROR VALUE
    status = npobj->_class->structVersion; //OK
    status = npobj->_class->hasMethod(npobj,L"existing_set_function"); //STATUS OK
    status = npobj->_class->enumerate(npobj, &arrayId, &count); //Privileged instruction ERROR
    status = npobj->_class->hasProperty(npobj, property); //STATUS OK
    status = npobj->_class->getProperty(npobj, property, &result); //STATUS OK BUT NO RESULT
    status = npobj->_class->invoke(npobj,L"existing_set_function",args,1,&result); //STATUS OK
    status = npobj->_class->invoke(npobj,L"existing_get_function",args,0,&result); //STATUS OK BUT NO RESULT
    status = npobj->_class->invokeDefault(npobj,args,0,&result); //STATUS OK BUT NO RESULT
    //END TEST
}
return npobj;
}

Наконец, вот методы plugin_instance для объявления ndata и pdata:

nsNPAPIPluginInstance::nsNPAPIPluginInstance()
{
  mNPP.pdata = NULL;
  mNPP.ndata = this;
}

nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
{

}

Заранее спасибо.

1 ответ

Хотя неясно, что означает "нет результата", ошибка привилегированной инструкции предполагает, что указатель функции отключен.

Я бы начал с:

  • Проверяя что structVersion >= NP_CLASS_STRUCT_VERSION_ENUM (иначе NPClass::enumerate не доступно)
  • Использование правильных заголовков npapi-sdk - имена типов указателей на функции указывают на то, что вы этого не делаете
  • Используя простой тестовый плагин, чтобы увидеть, что происходит на стороне плагина
  • Позаботьтесь о том, чтобы NPIdentifiers совпадают между вашим хост-приложением и плагином, то есть используйте общую строку->NPIdentifier mapping для кода хоста и NPN_GetStringIdentifier() - как опубликовано, это не может работать
  • Не проверяйте NPObject прямо в функции создания - плагин может настроить вещи для правильной работы только после NPN_CreateObject() возвращенный
Другие вопросы по тегам