以下代碼是來自firefox源庫的nsIEventTarget.h,但我很好奇爲什麼以及如何從nsIEventTarget.idl生成這個頭文件?爲什麼以及如何從接口定義語言(IDL)生成頭文件
接口定義語言
包含接口和類型庫定義被稱爲IDL文件,並具有.idl文件擴展名的文件。接口定義語言(IDL)不是一種編程語言,而是一種描述語言,用於描述由對象實現的接口。 IDL文件與C++頭文件類似。
以下代碼是nsIEventTarget.h。即使我編輯以下頭文件,它也會恢復並在重新構建後回滾到原始版本。
nsIEventTarget.h
/*
* DO NOT EDIT. THIS FILE IS GENERATED FROM ../../../dist/idl/nsIEventTarget.idl
*/
#ifndef __gen_nsIEventTarget_h__
#define __gen_nsIEventTarget_h__
#ifndef __gen_nsISupports_h__
#include "nsISupports.h"
#endif
#ifndef __gen_nsIRunnable_h__
#include "nsIRunnable.h"
#endif
/* For IDL files that don't want to include root IDL files. */
#ifndef NS_NO_VTABLE
#define NS_NO_VTABLE
#endif
#include "nsCOMPtr.h"
#include "mozilla/AlreadyAddRefed.h"
/* starting interface: nsIEventTarget */
#define NS_IEVENTTARGET_IID_STR "88145945-3278-424e-9f37-d874cbdd9f6f"
#define NS_IEVENTTARGET_IID \
{0x88145945, 0x3278, 0x424e, \
{ 0x9f, 0x37, 0xd8, 0x74, 0xcb, 0xdd, 0x9f, 0x6f }}
class nsIEventTarget : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IEVENTTARGET_IID)
nsresult Dispatch(nsIRunnable* aEvent, uint32_t aFlags) {
return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags);
}
enum {
DISPATCH_NORMAL = 0U,
DISPATCH_SYNC = 1U,
DISPATCH_AT_END = 2U
};
/* boolean isOnCurrentThread(); */
NS_IMETHOD IsOnCurrentThread(bool *_retval) = 0;
/* [binaryname(Dispatch),noscript] void dispatchFromC (in alreadyAddRefed_nsIRunnable event, in unsigned long flags); */
NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) = 0;
/* [binaryname(DispatchFromScript)] void dispatch (in nsIRunnable event, in unsigned long flags); */
NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) = 0;
/* [noscript] void delayedDispatch (in alreadyAddRefed_nsIRunnable event, in unsigned long delay); */
NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventTarget, NS_IEVENTTARGET_IID)
/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSIEVENTTARGET \
NS_IMETHOD IsOnCurrentThread(bool *_retval) override; \
NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) override; \
NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) override; \
NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) override;
/* Use this macro when declaring the members of this interface when the
class doesn't implement the interface. This is useful for forwarding. */
#define NS_DECL_NON_VIRTUAL_NSIEVENTTARGET \
nsresult IsOnCurrentThread(bool *_retval); \
nsresult Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags); \
nsresult DispatchFromScript(nsIRunnable *event, uint32_t flags); \
nsresult DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay);
/* Use this macro to declare functions that forward the behavior of this interface to another object. */
#define NS_FORWARD_NSIEVENTTARGET(_to) \
NS_IMETHOD IsOnCurrentThread(bool *_retval) override { return _to IsOnCurrentThread(_retval); } \
NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) override { return _to Dispatch(event, flags); } \
NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) override { return _to DispatchFromScript(event, flags); } \
NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) override { return _to DelayedDispatch(event, delay); }
/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
#define NS_FORWARD_SAFE_NSIEVENTTARGET(_to) \
NS_IMETHOD IsOnCurrentThread(bool *_retval) override { return !_to ? NS_ERROR_NULL_POINTER : _to->IsOnCurrentThread(_retval); } \
NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) override { return !_to ? NS_ERROR_NULL_POINTER : _to->Dispatch(event, flags); } \
NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) override { return !_to ? NS_ERROR_NULL_POINTER : _to->DispatchFromScript(event, flags); } \
NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) override { return !_to ? NS_ERROR_NULL_POINTER : _to->DelayedDispatch(event, delay); }
#if 0
/* Use the code below as a template for the implementation class for this interface. */
/* Header file */
class nsEventTarget : public nsIEventTarget
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIEVENTTARGET
nsEventTarget();
private:
~nsEventTarget();
protected:
/* additional members */
};
/* Implementation file */
NS_IMPL_ISUPPORTS(nsEventTarget, nsIEventTarget)
nsEventTarget::nsEventTarget()
{
/* member initializers and constructor code */
}
nsEventTarget::~nsEventTarget()
{
/* destructor code */
}
/* boolean isOnCurrentThread(); */
NS_IMETHODIMP nsEventTarget::IsOnCurrentThread(bool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* [binaryname(Dispatch),noscript] void dispatchFromC (in alreadyAddRefed_nsIRunnable event, in unsigned long flags); */
NS_IMETHODIMP nsEventTarget::Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* [binaryname(DispatchFromScript)] void dispatch (in nsIRunnable event, in unsigned long flags); */
NS_IMETHODIMP nsEventTarget::DispatchFromScript(nsIRunnable *event, uint32_t flags)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* [noscript] void delayedDispatch (in alreadyAddRefed_nsIRunnable event, in unsigned long delay); */
NS_IMETHODIMP nsEventTarget::DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* End of implementation class template. */
#endif
// convenient aliases:
#define NS_DISPATCH_NORMAL nsIEventTarget::DISPATCH_NORMAL
#define NS_DISPATCH_SYNC nsIEventTarget::DISPATCH_SYNC
#define NS_DISPATCH_AT_END nsIEventTarget::DISPATCH_AT_END
#endif /* __gen_nsIEventTarget_h__ */
nsIEventTarget.idl
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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"
#include "nsIRunnable.idl"
%{C++
#include "nsCOMPtr.h"
#include "mozilla/AlreadyAddRefed.h"
%}
native alreadyAddRefed_nsIRunnable(already_AddRefed<nsIRunnable>);
[scriptable, uuid(88145945-3278-424e-9f37-d874cbdd9f6f)]
interface nsIEventTarget : nsISupports
{
/* until we can get rid of all uses, keep the non-alreadyAddRefed<> version */
%{C++
nsresult Dispatch(nsIRunnable* aEvent, uint32_t aFlags) {
return Dispatch(nsCOMPtr<nsIRunnable>(aEvent).forget(), aFlags);
}
%}
/**
* This flag specifies the default mode of event dispatch, whereby the event
* is simply queued for later processing. When this flag is specified,
* dispatch returns immediately after the event is queued.
*/
const unsigned long DISPATCH_NORMAL = 0;
/**
* This flag specifies the synchronous mode of event dispatch, in which the
* dispatch method does not return until the event has been processed.
*
* NOTE: passing this flag to dispatch may have the side-effect of causing
* other events on the current thread to be processed while waiting for the
* given event to be processed.
*/
const unsigned long DISPATCH_SYNC = 1;
/**
* This flag specifies that the dispatch is occurring from a running event
* that was dispatched to the same event target, and that event is about to
* finish.
*
* A thread pool can use this as an optimization hint to not spin up
* another thread, since the current thread is about to become idle.
*
* These events are always async.
*/
const unsigned long DISPATCH_AT_END = 2;
/**
* Check to see if this event target is associated with the current thread.
*
* @returns
* A boolean value that if "true" indicates that events dispatched to this
* event target will run on the current thread (i.e., the thread calling
* this method).
*/
boolean isOnCurrentThread();
/**
* Dispatch an event to this event target. This function may be called from
* any thread, and it may be called re-entrantly.
*
* @param event
* The alreadyAddRefed<> event to dispatch.
* NOTE that the event will be leaked if it fails to dispatch.
* @param flags
* The flags modifying event dispatch. The flags are described in detail
* below.
*
* @throws NS_ERROR_INVALID_ARG
* Indicates that event is null.
* @throws NS_ERROR_UNEXPECTED
* Indicates that the thread is shutting down and has finished processing
* events, so this event would never run and has not been dispatched.
*/
[noscript, binaryname(Dispatch)] void dispatchFromC(in alreadyAddRefed_nsIRunnable event, in unsigned long flags);
/**
* Version of Dispatch to expose to JS, which doesn't require an alreadyAddRefed<>
* (it will be converted to that internally)
*
* @param event
* The (raw) event to dispatch.
* @param flags
* The flags modifying event dispatch. The flags are described in detail
* below.
*
* @throws NS_ERROR_INVALID_ARG
* Indicates that event is null.
* @throws NS_ERROR_UNEXPECTED
* Indicates that the thread is shutting down and has finished processing
* events, so this event would never run and has not been dispatched.
*/
[binaryname(DispatchFromScript)] void dispatch(in nsIRunnable event, in unsigned long flags);
/**
* Dispatch an event to this event target, but do not run it before delay
* milliseconds have passed. This function may be called from any thread.
*
* @param event
* The alreadyAddrefed<> event to dispatch.
* @param delay
* The delay (in ms) before running the event. If event does not rise to
* the top of the event queue before the delay has passed, it will be set
* aside to execute once the delay has passed. Otherwise, it will be
* executed immediately.
*
* @throws NS_ERROR_INVALID_ARG
* Indicates that event is null.
* @throws NS_ERROR_UNEXPECTED
* Indicates that the thread is shutting down and has finished processing
* events, so this event would never run and has not been dispatched, or
* that delay is zero.
*/
[noscript] void delayedDispatch(in alreadyAddRefed_nsIRunnable event, in unsigned long delay);
};
%{C++
// convenient aliases:
#define NS_DISPATCH_NORMAL nsIEventTarget::DISPATCH_NORMAL
#define NS_DISPATCH_SYNC nsIEventTarget::DISPATCH_SYNC
#define NS_DISPATCH_AT_END nsIEventTarget::DISPATCH_AT_END
%}
謝謝you.Do你瞭解IDL語法,這樣我可以修改IDL文件,並生成相應的頭file.'dispatchFromC' ,'dispatch'和'delayedDispatch'是在nsIEventTarget.idl中定義的函數。但在'nsIEventTarget.h'中,'dispatchFromC'和'dispatch'函數被註釋掉了。爲什麼會發生?我找到[syntax1](https://www.gta.ufrj.br/grad/OrbixWeb/pguide/idl.html)和[syntax2](http://www.ing.iac.es/ 〜docs/external/corba/idl-spec.pdf),但是我找不到從IDL到源文件(.h文件)的轉換規則。我需要在'nsIEventTarget.h'文件中添加一些其他函數。 – skytree
我的猜測是針對註釋函數,關聯的類型庫丟失....我的意思是說,如果您注意到idl文件,則「dispatch」與「DispatchFromScript」二進制名稱關聯。我的猜測是該類型庫缺失或錯誤。 – Naidu