將Mozilla源碼裏的內嵌Gecko示例winEmbed工程移植到VC

    最近在學習怎麼將Gecko嵌入到自己的應用程序中,下載了一份比較早一點的源碼在對照官方文檔痛苦地推進——網上相關資料確實相當缺乏,難道大家都各種webkit去了?我的計劃是先弄清怎麼用,讓程序跑起來,然後再根據官方文檔結構說明去定製,削減掉不需要的部分,折騰這個移植就花了我不少時間,果斷覺得應該跟大家分享之。廢話不說,直接上過程。

一、下載xulrunner源碼並編譯。我這裏用的1.9.2rc1版本,對應firefox 3.6.X。

    源碼下載地址:ftp://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/1.9.2rc1/source/

    編譯環境mozilla-build下載地址:http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-1.3.exe

    在解壓的源碼根目錄內新建一個".mozconfig"文件,我使用的內容是(其中有用的就是組建目標是xulrunner,啓動tests以生成示例程序):

   

mk_add_options MOZ_CO_PROJECT=xulrunner
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-xulrunner
ac_add_options --enable-application=xulrunner
#Uncomment the following line if you don't want to build JavaXPCOM:
ac_add_options --disable-javaxpcom
ac_add_options --disable-optimize
ac_add_options --enable-debug
ac_add_options --disable-vista-sdk-requirements
ac_add_options --with-windows-version=600
ac_add_options --enable-tests


    運行mozilla-build 1.3 中的start-msvc9.bat(因爲我使用的是Visual Studio 2008),切換到源碼根目錄下,運行“./configure",然後"make"。等待幾個小時(我的是用了四個小時左右)就OK了。

二、註冊GRE(Gecko運行時環境)。

    在經過上面第一步的編譯後,會在源碼根目錄下生成名爲dist的文件夾。"源碼根/dist/bin/"目錄下現在有xulrunner.exe等程序,在cmd下運行"xulrunner.exe --register-global"註冊GRE。這時候實際上就可以跑"源碼根/embedding/tests/winEmbed/winEmbed.exe"程序了,但是我們的目的是在VC下自己的工程裏嵌入Gecko,所以需要嘗試將這個示例工程winEmbed移植到VC中。

三、重點來了,將winEmbed移植到VC中。

    (1)新建工程”MozillaDemo",將winEmbed文件夾下的resource.h、SMALL.ICO、WebBrowserChrome.cpp、WebBrowserChrome.h、WindowCreator.cpp、WindowCreator.h、winEmbed.cpp、winEmbed.h、winEmbed.ICO、winEmbed.rc引入工程。編譯之,你會發現N多錯誤……

    (2)在VC++目錄中,include里加入"源碼根/dist/include",Library里加入"源碼根/dist/lib",bin里加入"源碼根/dist/bin"。

    (3)修改一些編譯選項。如在預編譯選項裏添加XPCOM_GLUE,XP_WIN,_CRT_SECURE_NO_WARNINGS。將Project->Propeties->Configuration Properties->C/C++->Language下的Treat wchar_t as Built-in Type設爲No (/Zc:wchar_t-),在引入庫裏添加xpcomglue.lib。總之讓編譯命令行看起來像下面這樣(具體爲何後面解釋):

從項目屬性的C/C++裏看到的編譯命令行:

 

/O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "XPCOM_GLUE" /D "XP_WIN" /D "_CRT_SECURE_NO_WARNINGS" /D "_MBCS" /FD /EHsc /MD /Gy /Zc:wchar_t- /Fo"Release\\" /Fd"Release\vc90.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt


 

從項目屬性的Linker裏看到的鏈接命令行:

 

/OUT:"E:\MZ_Test_Code\MozillaDemo\Release\MozillaDemo.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"Release\MozillaDemo.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"e:\MZ_Test_Code\MozillaDemo\Release\MozillaDemo.pdb" /OPT:REF /OPT:ICF /LTCG /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT xpcomglue.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib


 

    (4)在winEmbed.cpp文件裏添加一句

#pragma comment(lib, "D:/1.9.2rc1/xulrunner-1.9.2rc1.source/mozilla-1.9.2/profile/dirserviceprovider/standalone/profdirserviceprovidersa_s.lib")


    大功告成,編譯成功0 warning, 0 error。此時的程序也可以在別的機子上運行,但是需要將xulrunner.exe及其依賴文件拷到別的機子上並註冊GRE。

程序運行示意圖:

在自己編譯的xulrunner環境下跑會產生下面兩類錯誤,先忽略之讓程序跑起來。(用官方提供的xulrunner-sdk裏的程序來註冊GRE並運行程序無報錯)

 

    至於爲什麼要做(3)和(4),且聽我慢慢道來。

    1.爲什麼要添加預編譯選項XPCOM_GLUE

    在原版的winEmbed目錄下,有makefile文件,裏面有DEFINES += -DXPCOM_GLUE這麼一句。

    2.爲什麼要添加預編譯選項XP_WIN

    在winEmbed/makefile文件裏,有include $(DEPTH)/config/autoconf.mk這麼一句,而在這個autoconf.mk裏可以看到一大串的預編譯選項,我試了多番才得出這個非加不可的結論……(試!!!冏!)

    3.爲什麼要添加引入庫xpcomglue.lib,爲什麼要有(4)步驟

    在winEmbed/makefile文件裏,有LIBS = \
 $(DEPTH)/profile/dirserviceprovider/standalone/$(LIB_PREFIX)profdirserviceprovidersa_s.$(LIB_SUFFIX) \
 $(XPCOM_STANDALONE_GLUE_LDOPTS) \
 $(NULL)這麼一段,很顯然提示我們引入庫profdirserviceprovidersa_s,然後在autoconf.mk文件裏可以看到XPCOM_STANDALONE_GLUE_LDOPTS = $(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)這麼一個定義,所以也需要引入庫xpcomglue。

    4.爲什麼要將Project->Propeties->Configuration Properties->C/C++->Language下的Treat wchar_t as Built-in Type設爲No (/Zc:wchar_t-)

    很簡單,因爲編譯報錯提示唄……

(轉載請註明出處http://blog.csdn.net/mzlogin

 

    不執行這些操作將產生的錯誤:

不將Project->Propeties->Configuration Properties->C/C++->Language下的Treat wchar_t as Built-in Type設爲No (/Zc:wchar_t-)將報錯

WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: wchar_t const * __thiscall nsAString::BeginReading(void)const " (?BeginReading@nsAString@@QBEPB_WXZ)


拿掉預編譯選項"XP_WIN"會產生錯誤

1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __thiscall nsCOMPtr_base::assign_from_helper(class nsCOMPtr_helper const &,struct nsID const &)" (?assign_from_helper@nsCOMPtr_base@@QAEXABVnsCOMPtr_helper@@ABUnsID@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __thiscall nsCOMPtr_base::assign_from_qi(class nsQueryInterface,struct nsID const &)" (?assign_from_qi@nsCOMPtr_base@@QAEXVnsQueryInterface@@ABUnsID@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __thiscall nsCOMPtr_base::assign_with_AddRef(class nsISupports *)" (?assign_with_AddRef@nsCOMPtr_base@@QAEXPAVnsISupports@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __thiscall nsCreateInstanceByContractID::operator()(struct nsID const &,void * *)const " (??RnsCreateInstanceByContractID@@UBEIABUnsID@@PAPAX@Z)
1>WindowCreator.obj : error LNK2001: unresolved external symbol "unsigned int __cdecl NS_TableDrivenQI(void *,struct QITableEntry const *,struct nsID const &,void * *)" (?NS_TableDrivenQI@@YAIPAXPBUQITableEntry@@ABUnsID@@PAPAX@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: void __thiscall nsCOMPtr_base::assign_from_gs_contractid_with_error(class nsGetServiceByContractIDWithError const &,struct nsID const &)" (?assign_from_gs_contractid_with_error@nsCOMPtr_base@@QAEXABVnsGetServiceByContractIDWithError@@ABUnsID@@@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: void __thiscall nsCOMPtr_base::assign_from_gs_contractid(class nsGetServiceByContractID,struct nsID const &)" (?assign_from_gs_contractid@nsCOMPtr_base@@QAEXVnsGetServiceByContractID@@ABUnsID@@@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __thiscall nsGetInterface::operator()(struct nsID const &,void * *)const " (??RnsGetInterface@@UBEIABUnsID@@PAPAX@Z)


拿掉預編譯選項"XPCOM_GLUE"會產生錯誤

1>.\winEmbed.cpp(48) : error C2146: syntax error : missing ';' before identifier 'XRE_InitEmbedding'
1>.\winEmbed.cpp(48) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\winEmbed.cpp(48) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\winEmbed.cpp(48) : error C2365: 'XRE_InitEmbedding' : redefinition; previous definition was 'function'
1>        D:\1.9.2rc1\xulrunner-1.9.2rc1.source\mozilla-1.9.2\dist\include\nsXULAppAPI.h(355) : see declaration of 'XRE_InitEmbedding'
1>.\winEmbed.cpp(49) : error C2146: syntax error : missing ';' before identifier 'XRE_TermEmbedding'
1>.\winEmbed.cpp(49) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\winEmbed.cpp(49) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\winEmbed.cpp(49) : error C2365: 'XRE_TermEmbedding' : redefinition; previous definition was 'function'
1>        D:\1.9.2rc1\xulrunner-1.9.2rc1.source\mozilla-1.9.2\dist\include\nsXULAppAPI.h(390) : see declaration of 'XRE_TermEmbedding'
1>.\winEmbed.cpp(191) : error C3861: 'XPCOMGlueStartup': identifier not found
1>.\winEmbed.cpp(209) : error C2659: '=' : function as left operand
1>.\winEmbed.cpp(209) : error C2146: syntax error : missing ';' before identifier 'GetProcAddress'
1>.\winEmbed.cpp(210) : warning C4551: function call missing argument list
1>.\winEmbed.cpp(216) : error C2659: '=' : function as left operand
1>.\winEmbed.cpp(216) : error C2146: syntax error : missing ';' before identifier 'GetProcAddress'


拿掉引入庫"xpcomglue.lib"會產生錯誤

1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_StringContainerFinish
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_StringContainerFinish
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_StringContainerFinish
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringCopy
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: unsigned short const * __thiscall nsAString::BeginReading(void)const " (?BeginReading@nsAString@@QBEPBGXZ)
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol "public: unsigned short const * __thiscall nsAString::BeginReading(void)const " (?BeginReading@nsAString@@QBEPBGXZ)
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol "public: unsigned short const * __thiscall nsAString::BeginReading(void)const " (?BeginReading@nsAString@@QBEPBGXZ)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_StringContainerInit
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_StringContainerInit
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_StringContainerInit
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringSetDataRange
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringToUTF16
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringSetData
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __fastcall nsCOMPtr_base::assign_from_helper(class nsCOMPtr_helper const &,struct nsID const &)" (?assign_from_helper@nsCOMPtr_base@@QAIXABVnsCOMPtr_helper@@ABUnsID@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __fastcall nsCOMPtr_base::assign_from_qi(class nsQueryInterface,struct nsID const &)" (?assign_from_qi@nsCOMPtr_base@@QAIXVnsQueryInterface@@ABUnsID@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: void __fastcall nsCOMPtr_base::assign_with_AddRef(class nsISupports *)" (?assign_with_AddRef@nsCOMPtr_base@@QAIXPAVnsISupports@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: __thiscall nsCOMPtr_base::~nsCOMPtr_base(void)" (??1nsCOMPtr_base@@QAE@XZ)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringContainerInit
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_CStringContainerInit
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringContainerFinish
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_CStringContainerFinish
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __fastcall nsCreateInstanceByContractID::operator()(struct nsID const &,void * *)const " (??RnsCreateInstanceByContractID@@UBIIABUnsID@@PAPAX@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol _NS_CStringGetData
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "protected: void __thiscall nsSupportsWeakReference::ClearWeakReferences(void)" (?ClearWeakReferences@nsSupportsWeakReference@@IAEXXZ)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __stdcall nsSupportsWeakReference::GetWeakReference(class nsIWeakReference * *)" (?GetWeakReference@nsSupportsWeakReference@@UAGIPAPAVnsIWeakReference@@@Z)
1>WebBrowserChrome.obj : error LNK2001: unresolved external symbol "class nsIWeakReference * __cdecl NS_GetWeakReference(class nsISupports *,unsigned int *)" (?NS_GetWeakReference@@YAPAVnsIWeakReference@@PAVnsISupports@@PAI@Z)
1>WindowCreator.obj : error LNK2001: unresolved external symbol "unsigned int __fastcall NS_TableDrivenQI(void *,struct QITableEntry const *,struct nsID const &,void * *)" (?NS_TableDrivenQI@@YIIPAXPBUQITableEntry@@ABUnsID@@PAPAX@Z)
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol "unsigned int __fastcall NS_TableDrivenQI(void *,struct QITableEntry const *,struct nsID const &,void * *)" (?NS_TableDrivenQI@@YIIPAXPBUQITableEntry@@ABUnsID@@PAPAX@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: char const * __thiscall nsACString::BeginReading(void)const " (?BeginReading@nsACString@@QBEPBDXZ)
1>winEmbed.obj : error LNK2001: unresolved external symbol _GRE_GetGREPathWithProperties
1>winEmbed.obj : error LNK2001: unresolved external symbol _NS_NewNativeLocalFile
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: void __fastcall nsCOMPtr_base::assign_from_gs_contractid_with_error(class nsGetServiceByContractIDWithError const &,struct nsID const &)" (?assign_from_gs_contractid_with_error@nsCOMPtr_base@@QAIXABVnsGetServiceByContractIDWithError@@ABUnsID@@@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: void __fastcall nsCOMPtr_base::assign_from_gs_contractid(class nsGetServiceByContractID,struct nsID const &)" (?assign_from_gs_contractid@nsCOMPtr_base@@QAIXVnsGetServiceByContractID@@ABUnsID@@@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol _NS_CStringContainerInit2
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_CStringContainerInit2
1>winEmbed.obj : error LNK2001: unresolved external symbol _XPCOMGlueStartup
1>winEmbed.obj : error LNK2001: unresolved external symbol "public: virtual unsigned int __fastcall nsGetInterface::operator()(struct nsID const &,void * *)const " (??RnsGetInterface@@UBIIABUnsID@@PAPAX@Z)
1>winEmbed.obj : error LNK2001: unresolved external symbol _NS_StringContainerInit2
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_StringContainerInit2
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_StringContainerInit2
1>winEmbed.obj : error LNK2001: unresolved external symbol _NS_UTF16ToCString
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_DebugBreak
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_DebugBreak
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_LogAddRef
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_LogRelease
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_StringGetData
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_LogCOMPtrRelease
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_LogCOMPtrRelease
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol _NS_LogCOMPtrAddRef
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol _NS_LogCOMPtrAddRef
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol "public: unsigned int __fastcall nsGetServiceByContractIDWithError::operator()(struct nsID const &,void * *)const " (??RnsGetServiceByContractIDWithError@@QBIIABUnsID@@PAPAX@Z)
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol "public: unsigned int __fastcall nsQueryInterface::operator()(struct nsID const &,void * *)const " (??RnsQueryInterface@@QBIIABUnsID@@PAPAX@Z)
1>profdirserviceprovidersa_s.lib(nsProfileLock.obj) : error LNK2001: unresolved external symbol "public: unsigned int __fastcall nsQueryInterface::operator()(struct nsID const &,void * *)const " (??RnsQueryInterface@@QBIIABUnsID@@PAPAX@Z)
1>profdirserviceprovidersa_s.lib(nsProfileDirServiceProvider.obj) : error LNK2001: unresolved external symbol "public: unsigned int __fastcall nsGetServiceByContractID::operator()(struct nsID const &,void * *)const " (??RnsGetServiceByContractID@@QBIIABUnsID@@PAPAX@Z)


添加預編譯選項_CRT_SECURE_NO_WARNINGS用來消除警告

1>e:\mz_test_code\mozillademo\mozillademo\webbrowserchrome.cpp(375) : warning C4996: '_snprintf': This function or variable may be unsafe. Consider using _snprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        d:\program files\microsoft visual studio 9.0\vc\include\stdio.h(358) : see declaration of '_snprintf'
1>WindowCreator.cpp
1>winEmbed.cpp
1>e:\mz_test_code\mozillademo\mozillademo\winembed.cpp(163) : warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        d:\program files\microsoft visual studio 9.0\vc\include\string.h(157) : see declaration of 'strncpy'
1>e:\mz_test_code\mozillademo\mozillademo\winembed.cpp(198) : warning C4996: '_snprintf': This function or variable may be unsafe. Consider using _snprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        d:\program files\microsoft visual studio 9.0\vc\include\stdio.h(358) : see declaration of '_snprintf'
1>e:\mz_test_code\mozillademo\mozillademo\winembed.cpp(1086) : warning C4996: 'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        d:\program files\microsoft visual studio 9.0\vc\include\string.h(157) : see declaration of 'strncpy'


winEmbed.cpp文件裏添加#pragma comment(lib, "D:/1.9.2rc1/xulrunner-1.9.2rc1.source/mozilla-1.9.2/profile/dirserviceprovider/standalone/profdirserviceprovidersa_s.lib")
否則將產生錯誤

1>winEmbed.obj : error LNK2019: unresolved external symbol "unsigned int __cdecl NS_NewProfileDirServiceProvider(int,class nsProfileDirServiceProvider * *)" (?NS_NewProfileDirServiceProvider@@YAIHPAPAVnsProfileDirServiceProvider@@@Z) referenced in function "unsigned int __cdecl StartupProfile(void)" (?StartupProfile@@YAIXZ)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章