js调用gecko c++代码

时间:2021-08-20 06:36:28

        在移植gecko的时候发现一些问题,比如gecko连alert对话框这种基本的控件都没有默认实现,包括b2g,在firefox os(那个ui叫gaia)中是纯粹地用html实现的。起初觉得把gaia的的代码,拷过来点就是了,后来发现gaia写得有点复杂,会产生很多依赖,还不如直接用native的控件来实现。做法是参考android的firefox,用js处理部分逻辑,gui相关部分用java,就会产生js调java的需求。我是要js调c++,做法差不多。

        android中有一个叫AndroidBridge的类,把它注册为一个service,js就调用这个类的handleGeckoMessage()方法。这里简单介绍下操作步骤


 1. widget/YOUR_OS/nsINativeBridge.idl

/* 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/. */

#include "nsISupports.idl"

[scriptable, uuid(0e93d8f4-5392-48bc-9f4d-3a151773b14c)]
interface nsINativeBridge : nsISupports
{
  AString handleGeckoMessage(in AString message);
};


2.在相应的Makefile.in中的XPIDLSRCS增加这个idl

XPIDLSRCS	= \
	nsINativeBridge.idl

3.加入nsNativeBridge.h和nsNativeBridge.cpp。其实在idl生成的头文件的注释里包含了如何写这些文件的方法,稍微改改就行

widget/YOUR_OS/nsNativeBridge.h:

#ifndef nsNativeBridge_h__
#define nsNativeBridge_h__

#include "nsINativeBridge.h"

#define NS_NATIVEBRIDGE_CID \
{ 0x6a63ba66, 0xc72f, 0x431f, \
      { 0xb9, 0x7d, 0x42, 0x0b, 0xa5, 0xde, 0x19, 0xf5 } }

class nsNativeBridge : public nsINativeBridge
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSINATIVEBRIDGE

  nsNativeBridge();

private:
  ~nsNativeBridge();

protected:
};
#endif


nsNativeBridge.cpp

/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 * 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/. */

#include "nsNativeBridge.h"
#include "nsDOMClassInfoID.h"

NS_IMPL_ISUPPORTS1(nsNativeBridge, nsINativeBridge)

nsNativeBridge::nsNativeBridge()
{
}

nsNativeBridge::~nsNativeBridge()
{
}

/* void handleGeckoEvent (in AString message); */
NS_IMETHODIMP nsNativeBridge::HandleGeckoMessage(const nsAString & message, nsAString &aRet)
{
    nsCString cMessage = NS_ConvertUTF16toUTF8(message);
    aRet = NS_ConvertUTF8toUTF16(gGeckoAppShellFuncs->handleGeckoMessage(cMessage.get()));
    return NS_OK;
}

其中HandleGeckoMessage就是对应与idl中的handleGeckoMessage。这里我们吧message交给其他函数处理。作为测试,你可以在这里打印写东西

在nsWidgetFactory.cpp中注册.

加上

#include "nsNativeBridge.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeBridge)
NS_DEFINE_NAMED_CID(NS_NATIVEBRIDGE_CID);
在 static const mozilla::Module::CIDEntry kWidgetCIDs[] 加上

{ &kNS_NATIVEBRIDGE_CID, false, NULL, nsNativeBridgeConstructor },

在static const mozilla::Module::ContractIDEntry kWidgetContracts[]加上

{ "@mozilla.org/native/bridge;1", &kNS_NATIVEBRIDGE_CID },

在js中调用nsNativeBridge就是通过上面的contract id

4. 在Makefile.in中加上新增的cpp


这样这个bridge 就建好了,可以在js里测试
比如
const Cc = Components.classes;
let data = Cc["@mozilla.org/native/bridge;1"].getService(Ci.nsINativeBridge).handleGeckoMessage(JSON.stringify({ gecko: aMsg }));

注:这里js是gecko启动时调用的那些js,比如核心的shell.js,用户使用的js直接用js扩展好了