2013-09-16 3 views
0

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

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

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

У кого-нибудь есть идея вызывать методы 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 с ПолучитьЗначением функции:

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() 
{ 

} 

Заранее благодарен.

ответ

0

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

Я хотел бы начать с:

  • Проверка, что structVersion >= NP_CLASS_STRUCT_VERSION_ENUM (иначе NPClass::enumerateis not available)
  • Использование надлежащего npapi-sdk headers - ваши имена типов указателей функции предполагают, что вы не делаете, что
  • С помощью простого теста плагин, чтобы узнать, что происходит со стороной плагина.
  • Позаботьтесь о том, чтобы совпадение между вашим хост-приложением и плагином совпало, то есть используйте общую строку -> NPIdentifier m apping для главного кода и NPN_GetStringIdentifier() - как вывешено это не может работать
  • Не проверять NPObject прямо в функции создания - плагин может создавать вещи, чтобы работать должным образом только после того, как NPN_CreateObject() вернулся
+0

I hadn 't протестировал NP_CLASS_STRUCT_VERSION_ENUM, и эффективно функция перечисления недоступна, спасибо. Я изменил использование NPIdentifiers и протестировал программу на простом тестовом плагине. Он отлично работает: простой плагин вызывает NPN_utf8fromidentifier и метод вызывается. Но он не работает с плагином для импорта. Я также протестировал NPObject после возврата NPN_CreateObject(), но никакого эффекта: методы не вызывают и никакой вызов не выполняется для любых функций API. Возможно ли, что плагин использует некоторые ресурсы браузера вне функций API? – JeH

+0

Что вы имеете в виду, «методы не вызывают», возвращает ли она ошибку? Вы тестировали свое использование NPIdentifier с помощью своего тестового плагина, делая что-то вроде 'if (nameArg == NPN_GetStringIdentifier (" methodName ") ...' Всегда возможно, что плагин делает странные вещи или глючит, но это может быть гораздо проще. –

+0

Я имею в виду, что «метод не вызывает», что функция invoke возвращает false.Да, я тестировал использование NPIdentifier в тестовом плагине, и он отлично работает. Я объявляю свой NPidentifier следующим образом: NPIdentifier method = "method_name"; Контрольный плагин вызывает, как ожидалось, функцию NPN_utf8fromidentifier для преобразования, но другой плагин ничего не делает. Да, я уверен, что это более простая проблема. – JeH