2017-04-02 94 views
1

以下代碼是來自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 
%} 

回答

0

編譯一個.idl文件後,相應的頭文件與幾個C文件而產生。

所以在你的情況下,當你編譯nsIEventTarget.idl時,總是會重新生成nsIEventTarget.h

所以你的改變正在消失。

構建時創建IDL文件時的COM對象。 然後MIDL編譯器解析這個IDL來生成類型庫(.tlb),頭文件(在你的情況下)和一些代理文件。「.tlb」再次服務於那些想要使用生成「.tlb」的COM對象的應用程序。

你不需要知道很多關於MIDL編譯器的知識。 IDE(例如:visual studio)將負責所有這些操作。但仍然,如果你想知道更多關於它,你可以參考以下鏈接:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa367300(v=vs.85).aspx

+0

謝謝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

+0

我的猜測是針對註釋函數,關聯的類型庫丟失....我的意思是說,如果您注意到idl文件,則「dispatch」與「DispatchFromScript」二進制名稱關聯。我的猜測是該類型庫缺失或錯誤。 – Naidu

相關問題