NPAPIをざっくりやってみる (2)
NPAPIで定義したNPObjectなクラス等を実行したメソッド等から値を返したい場合、NPVariant* resultなのに処理すれば良いだと思うので、ちょいと色々やってみた
#include <iostream>
#include "plugin.h"
using namespace std;
void loga(const char* action) {
cerr << "[" << action << "]" << endl;
}
// std::stringからNPUTF8を生成
NPUTF8* CREATE_NPUTF8(const string s) {
size_t len = s.size();
NPUTF8* v = static_cast<NPUTF8*>(ppFuncs->memalloc(len + 1));
memcpy(v, s.c_str(), len);
return v;
}
// NPAPIライフサイクル上とかで注入しておく
NPP rootInstance;
// 返す値のNPObject (NPVariantType_Object)
class SampleNPObject : public NPObject {
public:
static NPClass npClass;
static NPObject* Create() {
return ppFuncs->createobject(rootInstance, &npClass);
}
// messageプロパティアクセスであればtrueを返す。falseを返すとプロパティ参照できずにGetProperty等の参照まで及ばない模様
static bool HasProperty(NPObject* pObj, NPIdentifier name) {
loga("HasProperty");
NPUTF8* propertyName = ppFuncs->utf8fromidentifier(name);
bool hasPropertyExists = strcmp(propertyName, "message") == 0;
ppFuncs->memfree(propertyName);
return hasPropertyExists;
}
// messageプロパティにアクセスされた際にNPUTF8なNPStringを返り値としてNPVariantに設定
static bool GetProperty(NPObject* pObj, NPIdentifier name, NPVariant* result) {
loga("GetProperty");
NPUTF8* propertyName = ppFuncs->utf8fromidentifier(name);
bool hasPropertyExists = strcmp(propertyName, "message") == 0;
if (hasPropertyExists) {
NPUTF8* s = CREATE_NPUTF8("hoge fuga foobar");
// 生成したNPUTF8を返り値としてNPVariantに設定
STRINGZ_TO_NPVARIANT(s, *result);
}
ppFuncs->memfree(propertyName);
return true;
}
};
class HogeNPObject : public NPObject {
public:
static NPClass npClass;
static bool HasMethod(NPObject *pObj, NPIdentifier name) {
loga("HasMethod");
NPUTF8 *methodName = ppFuncs->utf8fromidentifier(name);
bool result = strcmp(methodName, "eject") == 0;
ppFuncs->memfree(methodName);
return result;
}
static bool Invoke(NPObject* pObj, NPIdentifier name, const NPVariant *args, uint32_t argc, NPVariant* result) {
loga("Invoke");
NPUTF8 *methodName = ppFuncs->utf8fromidentifier(name);
bool isMatchMethodName = strcmp(methodName, "eject") == 0;
if (isMatchMethodName)
/* bool型なデータを返す場合
BOOLEAN_TO_NPVARIANT(true, *result);
*/
/* int32なデータを返す場合
INT32_TO_NPVARIANT(1, *result);
*/
// SampleNPObjectを返り値として返すようにNPVarinatに設定
OBJECT_TO_NPVARIANT(SampleNPObject::Create(), *result);
}
ppFuncs->memfree(methodName);
return isMatchMethodName;
}
};
NPClass HogeNPObject::npClass = {
NP_CLASS_STRUCT_VERSION,
NULL, // Alloc
NULL, // Dealloc
NULL, // Invalidate
HogeNPObject::HasMethod, // hasMethod
HogeNPObject::Invoke, // Invoke
NULL, // InvokeDefault
NULL, // hasProperty
NULL, // getProperty
NULL, // setProperty
NULL, // RemoveProerty
NULL, // enumerate
NULL // construct
};
NPClass SampleNPObject::npClass = {
NP_CLASS_STRUCT_VERSION,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
SampleNPObject::HasProperty,
SampleNPObject::GetProperty,
NULL,
NULL,
NULL,
NULL
};
んな感じで、NPVariantに適切なデータを設定する事でJS側から実行された際に返り値として返還させる事が出来る模様
で返り値としてObject型で返したい場合に、なんらかのEmptyなオブジェクトとかを返したり出来るとかそういうのがあるのか不明だったので、返すObjectな定義のNPObjectなクラスを作り(SampleNPObject)、それのインスタンス作って返すような感じ