Hi,
Now I am trying to use xpcom for callback function.
But I couldn't call gecko c++ function from gecko js using the XPCOM.
My test codes are below.
In gecko js (TESTManager.js), I try to call "TEST_setJSCallBack" function but
it did not be called.
I don't know why gecko c++ function can't be called from gecko js.
Please check my sample code and find my mistake or something.
Please anybody help me.
Thanks.
1. nsIDOMTESTManager.idl
----------------------------------------------------------------------------------------------
#include "nsISupports.idl"
[scriptable, function, uuid(2b9dfd66-d480-4b0d-9b15-8ed04858fd9c)]
interface IJSCallback : nsISupports {
boolean call(in int32_t bogus, in int32_t aData);
};
[scriptable, uuid(4a096156-1bd7-4f69-b7eb-89371ff82eb5)]
interface nsIDOMMozTESTManager : nsISupports
{
jsval TEST_Initialize(in jsval x, in jsval y, in jsval width, in jsval
height);
int32_t TEST_setJSCallBack(in IJSCallback aCallback);
void TEST_add(in int32_t first, in int32_t second);
void TEST_sum(in int32_t first, in int32_t second, in IJSCallback aCallback);
};
---------------------------------------------------------------------------------------------
2. TESTManager.h
---------------------------------------------------------------------------------------------
#ifndef DOM_TEST_TESTMANAGER_H
#define DOM_TEST_TESTMANAGER_H
#include "nsProxyRelease.h"
#include "nsIDOMTESTManager.h"
#define NSDOMMOZTESTMANAGER_CLASSNAME "TEST Manager"
#define NSDOMMOZTESTMANAGER_CID { 0xfb585e70, 0xef3d, 0x42e9, {
0x9b, 0x9a, 0xf8, 0x53, 0xcb, 0x4c, 0x43, 0x14 } }
#define NSDOMMOZTESTMANAGER_CONTRACTID "@mozilla.com/MozTESTManager;1"
class nsDOMMozTESTManager : public nsIDOMMozTESTManager
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMMOZTESTMANAGER
nsDOMMozTESTManager();
private:
~nsDOMMozTESTManager();
protected:
/* additional members */
nsCOMPtr<IJSCallback> m_JSCallBack;
};
class CJSCallback : public IJSCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IJSCALLBACK
CJSCallback();
private:
~CJSCallback();
protected:
/* additional members */
};
#endif // DOM_TEST_TESTMANAGER_H
---------------------------------------------------------------------------------------------
3. TESTManager.cpp
---------------------------------------------------------------------------------------------
#include "base/basictypes.h"
#include "TESTManager.h"
#include "TESTCommon.h"
using namespace mozilla;
NS_IMPL_ISUPPORTS1(nsDOMMozTESTManager, nsIDOMMozTESTManager)
nsDOMMozTESTManager::nsDOMMozTESTManager()
{
/* member initializers and constructor code */
DOM_TEST_LOGI("nsDOMMozTESTManager : constructor");
}
nsDOMMozTESTManager::~nsDOMMozTESTManager()
{
/* destructor code */
DOM_TEST_LOGI("nsDOMMozTESTManager : destructor");
}
NS_IMPL_CLASSINFO(nsDOMMozTESTManager, NULL, 0, NSDOMMOZTESTMANAGER_CID)
NS_IMPL_ISUPPORTS1_CI(nsDOMMozTESTManager, nsIDOMMozTESTManager)
/* jsval TEST_Initialize (in jsval x, in jsval y, in jsval width, in jsval
height); */
NS_IMETHODIMP nsDOMMozTESTManager::TEST_Initialize(const JS::Value & x, const JS::Value
& y, const JS::Value & width, const JS::Value & height, JS::Value *_retval)
{
DOM_TEST_LOGI("nsDOMMozTESTManager::TEST_Initialize");
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void SetJSCallBack (in IJSCallback aCallback); */
NS_IMETHODIMP nsDOMMozTESTManager::TEST_setJSCallBack(IJSCallback *aCallback,
int32_t *_retval)
{
DOM_TEST_LOGI("nsDOMMozTESTManager::TEST_SetJSCallBack");
nsDOMMozTESTManager::m_JSCallBack = aCallback;
*_retval = 123;
return NS_OK;
}
/* void add (in int32_t first, in int32_t second); */
NS_IMETHODIMP nsDOMMozTESTManager::TEST_add(int32_t first, int32_t second)
{
DOM_TEST_LOGI("nsDOMMozTESTManager::TEST_add");
bool ret = true;
nsDOMMozTESTManager::m_JSCallBack->Call((int32_t)0, first+second, &ret);
return NS_OK;
}
/* void sum (in int32_t first, in int32_t second, in IJSCallback aCallback); */
NS_IMETHODIMP nsDOMMozTESTManager::TEST_sum(int32_t first, int32_t second,
IJSCallback *aCallback)
{
DOM_TEST_LOGI("nsDOMMozTESTManager::TEST_sum : first = %d, second = %d,
aCallback = %x\n", first, second, aCallback);
PRBool ret = true;
TEST_add(first, second);
return NS_OK;
}
NS_IMPL_ISUPPORTS1(CJSCallback, IJSCallback)
CJSCallback::CJSCallback()
{
DOM_TEST_LOGI("CJSCallback::CJSCallback");
}
CJSCallback::~CJSCallback()
{
DOM_TEST_LOGI("CJSCallback::~CJSCallback");
}
/* boolean call (in int32_t bogus, in int32_t aData); */
NS_IMETHODIMP CJSCallback::Call(int32_t bogus, int32_t aData, bool *_retval)
{
DOM_TEST_LOGI("CJSCallback::Call : bogus = %d, aData = %d\n", bogus,
aData);
return NS_OK;
}
---------------------------------------------------------------------------------------------
4. TESTCommon.h
---------------------------------------------------------------------------------------------
#ifndef DOM_TEST_TESTCOMMON_H
#define DOM_TEST_TESTCOMMON_H
#define PR_LOGGING
#ifndef __func__
#ifdef __FUNCTION__
#define __func__ __FUNCTION__
#else
#define __func__ __FILE__
#endif
#endif
#ifndef NAN
#define NAN std::numeric_limits<double>::quiet_NaN()
#endif
#include "nsThreadUtils.h"
#include "nsIDOMTESTManager.h"
#include "prlog.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gTESTLog;
#define DOM_TEST_LOG( type, ... ) PR_LOG(gTESTLog, (PRLogModuleLevel)type, (
__VA_ARGS__ ))
#else
#define DOM_TEST_LOG( type, ... )
#endif
#define DOM_TEST_LOGA( ... ) DOM_TEST_LOG( 0, __VA_ARGS__ )
/**
* From the least to the most output.
*/
enum {
DOM_TEST_LOG_NOTHING,
DOM_TEST_LOG_ERROR,
DOM_TEST_LOG_WARNING,
DOM_TEST_LOG_INFO,
DOM_TEST_LOG_TRACE,
DOM_TEST_LOG_REFERENCES
};
/**
* DOM_CAMERA_LOGR() can be called before 'gCameraLog' is set, so
* we need to handle this one a little differently.
*/
#ifdef PR_LOGGING
#define DOM_TEST_LOGR( ... ) \
do { \
if (gTESTLog) { \
DOM_TEST_LOG( DOM_TEST_LOG_REFERENCES, __VA_ARGS__ ); \
} \
} while (0)
#else
#define DOM_TEST_LOGR( ... )
#endif
#define DOM_TEST_LOGT( ... ) DOM_TEST_LOG( DOM_TEST_LOG_TRACE, __VA_ARGS__
)
#define DOM_TEST_LOGI( ... ) DOM_TEST_LOG( DOM_TEST_LOG_INFO, __VA_ARGS__ )
#define DOM_TEST_LOGW( ... ) DOM_TEST_LOG( DOM_TEST_LOG_WARNING,
__VA_ARGS__ )
#define DOM_TEST_LOGE( ... ) DOM_TEST_LOG( DOM_TEST_LOG_ERROR, __VA_ARGS__
)
#ifdef PR_LOGGING
static inline void nsLogAddRefTEST(const char *file, uint32_t line, void* p,
uint32_t count, const char *clazz, uint32_t size)
{
if (count == 1) {
DOM_TEST_LOGR("++++++++++++++++++++++++++++++++++++++++");
}
DOM_TEST_LOGR("%s:%d : TESTREF-ADD(%s): this=%p, mRefCnt=%d\n", file, line,
clazz, p, count);
}
static inline void nsLogReleaseTEST(const char *file, uint32_t line, void* p,
uint32_t count, const char *clazz, bool abortOnDelete)
{
DOM_TEST_LOGR("%s:%d : TESTREF-REL(%s): this=%p, mRefCnt=%d\n", file, line,
clazz, p, count);
if (count == 0) {
if (!abortOnDelete) {
DOM_TEST_LOGR("----------------------------------------");
} else {
DOM_TEST_LOGR("---------- ABORTING ON DELETE ----------");
*((uint32_t *)0xdeadbeef) = 0x266230;
}
}
}
#ifdef NS_LOG_ADDREF
#undef NS_LOG_ADDREF
#endif
#ifdef NS_LOG_RELEASE
#undef NS_LOG_RELEASE
#endif
#define NS_LOG_ADDREF( p, n, c, s ) nsLogAddRefTEST(__FILE__, __LINE__, (p),
(n), (c), (s))
#ifdef DOM_TEST_DEBUG_REFS_ABORT_ON_DELETE
#define NS_LOG_RELEASE( p, n, c ) nsLogReleaseTEST(__FILE__, __LINE__, (p),
(n), (c), DOM_TEST_DEBUG_REFS_ABORT_ON_DELETE)
#else
#define NS_LOG_RELEASE( p, n, c ) nsLogReleaseTEST(__FILE__, __LINE__, (p),
(n), (c), false)
#endif
#endif // PR_LOGGING
#endif // DOM_TEST_TESTCOMMON_H
---------------------------------------------------------------------------------------------
5. TESTManager.js
---------------------------------------------------------------------------------------------
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* static functions */
const DEBUG = true;
function debug(aStr) {
if (DEBUG)
dump("TESTManager: " + aStr + "\n");
}
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
Cu.import("resource://gre/modules/ctypes.jsm");
const TESTMANAGER_CONTRACTID = "@mozilla.org/testManager;1";
const TESTMANAGER_CID =
Components.ID("{4a096156-1bd7-4f69-b7eb-89371ff82eb5}");
const nsIDOMMozTESTManager = Ci.nsIDOMMozTESTManager;
const nsIClassInfo = Ci.nsIClassInfo;
let library = ctypes.open("libTEST.so");;
let Test_Initialize;
var test111 = function(sum) {
debug("test111 : " + sum);
}
function TESTManager()
{
debug("Constructor");
}
TESTManager.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
classID : TESTMANAGER_CID,
QueryInterface : XPCOMUtils.generateQI([nsIDOMMozTESTManager,
Ci.nsIDOMGlobalPropertyInitializer]),
classInfo : XPCOMUtils.generateCI({ classID: TESTMANAGER_CID,
contractID: TESTMANAGER_CONTRACTID,
classDescription: "TESTManager",
interfaces: [nsIDOMMozTESTManager],
flags: nsIClassInfo.DOM_OBJECT }),
TEST_Initialize: function TEST_Initialize(x, y, width, height) {
var that = this;
var com = Components.classes["@mozilla.org/testManager;1"]
.getService(Components.interfaces.nsIDOMMozTESTManager);
debug(com);
var ret = com.TEST_setJSCallBack(test111);
debug("SetJSCallBack = " + ret);
// START ====== TEST Initialize
Test_Initialize = library.declare("Test_Initialize",
ctypes.default_abi,
ctypes.int32_t,
ctypes.int32_t,
ctypes.int32_t,
ctypes.int32_t,
ctypes.int32_t);
debug ("Test_Initialize = " + Test_Initialize);
var result = Test_Initialize(x, y, width, height);
debug ("Test_Initialize : result = " + result);
// return result;
// END ====== TEST Initialize
},
TEST_setJSCallBack: function TEST_setJSCallBack(aCallback) {
debug("TEST_setJSCallBack 1111 = " + aCallback);
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TESTManager])
---------------------------------------------------------------------------------------------