ATL,Active Template LibraryActive Template Library,是一種微軟程式庫,支援利用C++語言編寫ASP代碼以及其它ActiveX程式。通過Active Template Library,可以建立COM組件,然後 通過ASP頁面中的指令碼對COM對象進行調用。這種COM組件可以包含屬性頁面、對話方塊等等控制項。
ATL無疑是目前幾種主流技術中最難學且相對邊緣化的一門技術。隨著Internet技術的發展,Microsoft將ActiveX技術作為其網路戰略的一個重要組成部分大力推廣,然而使用MFC開發的 ActiveX Control,代碼冗餘量大(所謂的“肥代碼 Fat Code”),而且必須要依賴於MFC的運行時刻庫才能正確地運行。雖然MFC的運行時刻庫只有部分功能與COM有關,但是由於MFC的繼承實現的本質,ActiveX Control必須背負運行時刻庫這個沉重的包袱。如果採用靜態串連MFC運行時刻庫的方式,這將使ActiveX Control代碼過於龐大,在網路上傳輸時將佔據寶貴的網路頻寬資源;如果採用動態串連MFC運行時刻庫的方式,這將要求瀏覽器一方必須具備MFC的運行時刻庫支援。總之MFC對COM技術的支援在網路應用的環境下也顯得很不靈活。解決上述COM開發方法中的問題正是ATL的基本目標。
上面是對ATL簡單介紹, 在我前幾天博文定製IE瀏覽器的尖兵利器 - BHO
中提到怎麼打造自己的瀏覽器, 對瀏覽器功能進行擴充. 源於最近有一項目, 客戶想從一套國家級系統中提取資料, 我們不能夠動那套系統任何一個功能, 那怕是加幾個頁面或者加個JavaScript函數. 但是我們確實需要那套系統能夠提供一些必要的資訊給目前使用者想上馬的系統, 因為這套系統是對國家局系統的補充完善, 整合了一些協助工具功能進來, 是為稽查人員核查相關資料提供音視頻相關佐證材料.
所以前期調研技術實現方面, 我想到了BHO + ActiveX技術, 經測試技術上確實可行, 使用者通過點擊我們在網頁右鍵菜單中新增的相關功能表項目, 由JavaScript來解析
當前頁面資料, 然後調用ActiveX控制項與中心服務程式進行Socket通訊, 發送採集的資訊到中心伺服器. 如果你對ATL ActiveX控制項開發不瞭解, 可以先看看VCKBASE
上的用ATL開發和部署ActiveX控制項的簡單例子這篇文章(使用Vs 2003開發), 其提供的例子非常簡單, 只有一個GetString(BSTR bstr)方法. 想更加深入瞭解控制項屬性, 事件, 屬性對話方塊編程, GDI繪製, 指令碼引擎等開發方面內容, 可以看楊老師那篇用 ATL ActiveX 繪製任意平面函數的曲線. 開發控制項過程還算比較順利,
只是最終在編譯Realease版本時候出現了一個LIBCMT.LIB(crt0.obj) : error LNK2001: unresolved external symbol _main錯誤. 也在網上找到瞭解決方法(
來自小飛百度空間文章) .
"最近寫一個ATL的項目,最終realease的時候出現了這個問題,當時嚇了一跳,後來發現了問題,代碼沒有錯誤是配置搞錯了,因為debug沒有任何問題。
出錯原因:使用了CRT函數,這些函數需要CRT啟動代碼,就會出現這種連結錯誤。因為Release配置的Preprocessor definitions中定義了_ATL_MIN_CRT,它把將CRT啟動代碼從Dll中刪除了。
最簡單的辦法就是工程設定中刪除_ATL_MIN_CRT,但是這樣以來就會增加編譯後檔案的大小。或者工程設定的ignore libraries中輸入Libcmt.lib。再次連結時,到幾個“unresolved external”的錯誤,然後你就開始Look for things that you think may be pulling in the startup code and remove them if you can.Instead, use their Win32 equivalents. For example, use lstrcmp() instead of strcmp(). Known functions that require CRT startup code are some of the string and floating point functions.
看了看微軟的文檔
ATL支援把一個伺服器編連最佳化成最小尺寸或者依賴性最小。我們可以定義三個前置處理器符號來影響伺服器的最佳化。
_ATL_MIN_CRT 伺服器不連結標準的C/C++運行庫
_ATL_DLL 伺服器動態連結工具函數庫atl.dll
_ATL_STATIC_REGISTRY 伺服器靜態連結對組件註冊的支援
如果定義了前置處理器符號_ATL_MIN_CRT,將不連結C/C++運行庫,並且ATL提供了函數malloc、realloc、new和delete的一個實現。當定義了這個符號時,不能調用任何其他的C/C++運行庫的函數。
ATL嚮導產生的ATL工程為所有的Release版本的編連定義了_ATL_MIN_CRT,但是沒有為Debug版本定義這個符號。
Debug配置沒有定義這三個符號中的任何一個。
RelMinSize配置定義了_ATL_MIN_CRT和_ATL_DLL。
RelMinDependency配置定義了_ATL_MIN_CRT和_ATL_STATIC_REGISTRY。
隱約記得,VC的sp6確實解決了這個bug,還是我比較懶,沒有給vc打servicepack6。發現 開啟stdafx.cpp,注釋掉#include <atlimpl.cpp>也是可以的。
msdn描述
INFO: LNK2001 Error ATL Release Build
ID: Q165076
--------------------------------------------------------------------------------
The information in this article applies to:
Microsoft Active Template Library, versions 2.0, 2.1, 3.0
--------------------------------------------------------------------------------
SUMMARY
Microsoft Active Template Library COM AppWizard generates a release build of your project using macro _ATL_MIN_CRT. Selecting this configuration causes the C run-time (CRT) library startup code to not be linked into your project. If you use functions or code in your project that require the use of the C run-time library startup code, you may experience LNK2001 - unresolved external errors when you try to build the release version of your project.
MORE INFORMATION
You can use some C run-time functions without requiring the CRT startup code. Examples include the mem* functions. Other functions require the CRT startup code. CRT string comparisons for example require the startup code as the CRT initializes some tables used for comparing. Global objects that have constructors also require the startup code. In Visual C++ 5.0, statically linking the startup code adds about 25K to your image (in Visual C++ 4.2 it is about 20K).
Following are some suggestions for finding the cause of the LNK2001 errors:
In the linker options there is an "ignore libraries" edit box. Enter Libcmt.lib into it, and build. You get several unresolved externals. This list is everything that you are using from the CRT. Look for things that you think may be pulling in the startup code and remove them if you can.
Don't ignore Libcmt.lib, but turn on the verbose flag for the linker. From this, you can see what is triggering CRT startup code to get pulled in.
If you decide that you really need the startup code, then remove the _ATL_MIN_CRT define from the project settings. You can also dynamically link to the CRT, which reduces your image size but requires the CRT's DLL. If you turn on exception handling you have to pull in the startup code. Even when building minsize the default is to statically link to the CRT and use _ATL_MIN_CRT."
最後值得一提是ActiveX當前最大問題是瀏覽器安全限制, 在一般情況下不太可能允許執行; 那就需要客戶電腦對特定網址降低安全性, 當然最好處理方式是對控制項
進行認證簽名, 標識其為安全控制項. 還好只要把右鍵功能表項目的網址指向中心伺服器上的相關頁面, 那隻要中心伺服器註冊這個控制項的DLL就可以, 然後由它轉寄資料回訪
問的用戶端, 通知客戶電腦上的視頻監控用戶端程式作出相應響應. 至於採用這種方式來解決, 主要是考慮到使用者體驗, 把所有功能都整合到其原先的B/S上, 互動操作
方便. 當然我們可以要求使用者自己把頁面上相關資料輸入到我們系統提供的介面進行錄影查詢回放等相關操作, 但從使用者使用方面, 操作性上來說不是太好.