2008年1月31日 星期四

WinCE DLL build 一些小經驗

最近對USB serial function driver感興趣,WinCE 下serial usb driver位于WINCE600 \ PUBLIC \ COMMON \ OAK \ DRIVERS \ USBFN \CLASS \ SERIAL下面。看看它的sources和def檔,sources生成SerialUSBFn_lib.lib檔,def檔定義了COM_Init等export function。

SerialUSBFn_lib.lib是生成SerialUSBFn.dll的必要target library之一,這個可以打開SerialUSBFn.map,搜索WriteDataOnce串:
0001:00006018 ?WriteDataOnce@CUsbFuncPipe@@AAAXPAEPAK@Z 10007018 f serialusbfn_lib:usbfndrv.obj
顯示,WriteDataOnce是CUsbFuncPipe 類的函數,位于serialusbfn_lib.lib中。對照源代碼,WriteDataOnce確實是CUsbFuncPipe的成員函數。

SerialUSBFn.dll在哪里生成的呢?打開WINCE600 \ PUBLIC \ COMMON \ CESYSGEN \ Makefile,搜索SerialUSBFn得到:
serialusbfn:: com_mdd2 serpddcm ceddk ufnclientlib
  @set TARGETLIBS=$(OWNSTATICLIB) $(CEDDKLIB) $(SG_OUTPUT_OAKLIB) \ com_mdd2.lib $(SG_OUTPUT_OAKLIB) \ serpddcm.lib $(SG_OUTPUT_OAKLIB) \ ufnclientlib.lib
好像沒看到serialusbfn以來與serialusbfn_lib.lib?注意第一個變量OWNSTATICLIB在一開始被定義為:
OWNSTATICLIB=$(SG_INPUT_LIB)\$@_lib.lib
展開來就是serialusbfn_lib.lib。

此外,SerialUSBFn_lib.lib的def檔里有定義COM_Init,但這個函數在哪里實現的呢?同樣搜索SerialUSBFn.map:
0001:000023d0 COM_Init 100033d0 f com_mdd2:mdd.obj
應該是在 com_mdd2.lib中實現的。這個com_mdd2就位于WINCE600 \ PUBLIC \ COMMON \ OAK \ DRIVERS \ SERIAL \ COM_MDD2 \ 目錄下。

用dumpbin /exports SerialUSBFn.dll知道該dll的輸出函數就是def檔中定義的COM_Init等函數。

.map文件是個蠻重要的文件,WinCE中存在很多同名的函數,當不確定那個函數是真正被調用的,可以在這個函數中搜索一下,看它是在哪個lib中定義的,幫組我們找到正確的源代碼。