這裏有兩個選項 - import
或importlib
。
不幸的是,import
導致導入文件中的接口和coclass定義出現在已編譯的.tlb
文件中。這會導致註冊和代理時出現各種問題。我不建議使用import
。
importlib
不會遭受同樣的問題。但是,這意味着您必須首先將.idl
編譯爲.tlb
,然後才能導入它。從.idl
編譯一個.tlb
,其中包含您的依賴關係(IFace
)。然後使用importlib
關鍵字從.idl
中引用包含您的從屬(IProcessor
)的類型庫。你的第二個.idl
文件將是這個樣子:
[...]
library ProcessorLibrary
{
importlib("FaceLibrary.tlb");
[...]
interface IProcessor
{
HRESULT ProcessFace(FaceLibrary.IFace* face)
};
}
對於importlib
說法,你可以使用一個完全合格的路徑或相對路徑。如果使用相對路徑,它將嘗試使用環境變量PATH
來解析該文件名。如果您正在使用Visual Studio進行此操作,則可以在項目屬性中設置搜索路徑 - 在VC++ Directories
下,將搜索路徑放入Executable Directories
變量中。這對應於.vcxproj
文件中的ExecutablePath
屬性。
請注意,importlib
中的「FaceLibrary
」與接口中的「FaceLibrary
」不同。 importlib
中的那個是.tlb
文件的名稱。接口中使用的標識符是類型庫名稱(與第一個.idl
文件中的library
鍵一起使用的名稱)。
爲了編譯第二個.idl
文件生成的C++,你必須做兩件事。第一個.tlb
需要手動#import
編輯到第二個C++項目中,就像您必須在第二個.idl
中使用importlib
一樣。那麼你需要處理C++命名空間問題。不幸的是,midl.exe
不會生成使用名稱空間的代碼。雖然第二個.idl
文件包含FaceLibrary.IFace
,但生成的C++只包含IFace
。這意味着您需要將第一個.tlb
導入到不使用名稱空間的C++項目中,或者您必須使用typedef。
使用沒有命名空間:
#import "FaceLibrary.tlb" no_namespace
#include "Processor_i.h"
使用命名空間:
#import "FaceLibrary.tlb"
typedef FaceLibrary.IFace IFace;
#include "Processor_i.h"
相對路徑的分辨率在#import
的工作方式相同,如importlib
。
難道你不能把所有的C++放在一個.idl文件中嗎(帶有前向聲明)? –
@SimonMourier沒有不幸的。有不同的工作方式。一個是exemodule,它爲每個主com對象的使用生成單獨的進程。和其他是DLL。該架構相當繁瑣,我試圖簡化詢問,爲了簡潔 –
這是一個基本的細節。其中一個接口指針必須始終被編組,因爲它的服務器在進程外,你不能編組一個void *。不要這樣做。 –