2010年5月25日 星期二

Link error: unresolved external symbol __imp_CommandBar_XXXXXX

在編譯 CE下的 format程式時,選擇 windows program, 並且編譯 沒有問題。
因為要link storeapi.lib
但是當我在lib path 中include C:\WINCE\PUBLIC\COMMON\OAK\LIB\MIPS\RETAIL 時
會出現以下錯



1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_AddAdornments referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_InsertMenubar referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_Create referenced in function "long __cdecl WndProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WndProc@@YAJPAUHWND__@@IIJ@Z)
1>ceformatw.obj : error LNK2019: unresolved external symbol __imp_CommandBar_Show referenced in function "int __cdecl InitInstance(struct HINSTANCE__ *,int)" (?InitInstance@@YAHPAUHINSTANCE__@@H@Z)

調查後發現 在Standard SDK下的 Commctrl.lib 和 PUBLIC\COMMON\OAK\LIB下的 Commctrl.lib 並不相同

SDK下的 Commctrl.lib 只是一個 dll import library
OAK\LIB 下的則為實際的 static library

但是Standard SDK 下的Commctrl.h 和 PUBLIC\COMMON\SDK\INC 下的 Commctrl.h
是一樣的。

在 commctrl.h

//
// Define API decoration for direct importing of DLL references.
//
#ifndef WINCOMMCTRLAPI
#if !defined(_COMCTL32_) && defined(_WIN32)
#define WINCOMMCTRLAPI DECLSPEC_IMPORT
#else
#define WINCOMMCTRLAPI
#endif
#endif // WINCOMMCTRLAPI



IN winnt.h
#if (defined(_M_MRX000) || defined(_M_IX86) || defined(_M_ALPHA) || defined(_M_PPC) || defined(_M_IA64)) && !defined(MIDL_PASS)
#define DECLSPEC_IMPORT __declspec(dllimport)
#else
#define DECLSPEC_IMPORT
#endif

所以 __imp_ 是Microsoft 為 dllimport 所加上的修飾詞

目前能想到的暫時解決方法(非完美)為
把Standard SDK 的Lib 也加入 在PUBLIC\COMMON\OAK\LIB 的前面





主要是 WINCOMMCTRLAPI 的定義
不應該跑到上面 DECLSPEC_IMPORT



2010年5月17日 星期一

Warning C4512 assignment operator could not be generated

The compiler will also generate an assignment operator function for a class that does not define one. This assignment operator is simply a member wise copy of the data members of an object. Because const data items cannot be modified after initialization, if the class contains a const item, the default assignment operator would not work.




You can resolve the C4512 warning for this code in one of three ways:



•Explicitly define an assignment operator for the class.



•Remove const from the data item in the class.



•Use the #pragma warning statement to suppress the warning.


這個Warning (Level 4)是因為編譯器會自動產生 default assignment operator
但是如果 class 裡面有 const data member,  因為 const data member 在 initialize 之後
就無法改變( assign )其值,所以沒有辦法產生default assignment operator。

2010年5月14日 星期五

WINCE底下的錄音 ( Waveform API)

最近要用到 voice note 功能,把之前寫的錄音程式拿出來。
測試之後發現了2個問題,一個是聲音之間會有中斷,如 1 2 3 4 5 6 7 8 會變成 1 3 5 6 8
第二個問題是錄音的尾段部份消失。


聲音之間有中斷是因為 buffer 只有allocate 一個,
使用 double buffer or multiple buffer 就可以解決
( waveInPrepareHeader 對每個buffer 只需call 一次)

錄音尾部消失是因為最後一個chunk的data沒有寫入。
當呼叫 waveInStop() 停止錄音,並不會call waveInProc = ="
waveInProc 是只有當buffer 滿的時候才會被呼叫。
所以要改用別的方法...

If there are any buffers in the queue, the current buffer will be marked as done (the dwBytesRecorded member in the header will contain the length of data)

判斷buffer done , 由 WAVEHDR 中的 dwFlags
是否為WHDR_DONE

再來從The code project 看到他人所寫的code,
要寫成wave檔,可用mmioWrite函式
但是WINCE下沒有,所以... 要自己寫檔頭,
以及結尾時 寫在檔頭部份的長度。

第三個問題是
如果沒有正確的 waveInClose()  (傳回值為WAVERR_STILLPLAYING  0x21)
則下一次無法正常打開device  waveInOpen()
必須要重開機。

2010年5月5日 星期三

AAC in QuickTime 7.6.6 error 2041 2048

!從7.6.5 換成 7.6.6之後
好像之前用 mp4muxer mux 的聲音+影像檔無法撥放
出現 error 2041: an invalid sample description was found in the movie

目前還不清楚哪裡出錯
試過各種mux參數還是無法成功

下面這個網站說要用
-aac-profile=4
http://bahut.alma.ch/2010/02/quicktime-error-2041-invalid-sample.html

還在試驗中
(VLC撥放ok)

libfaac
在libfaac 的 gui 版本中 只能選擇 Low Complexity 其它的被mark 掉了
但是實際上又沒設好這個值 所以 config->aacObjectType 為0

/* AAC object types */

#define MAIN 1
#define LOW 2
#define SSR 3
#define LTP 4
 
if (config->aacObjectType == SSR) /* Set to LTP */

config->aacObjectType = LTP;
 
(解決了,把 config->aacObjectType = LOW 然後再mux,ok)

後來又遇到開檔錯誤 2048, 無法分辨其格式
經過實驗後 發現 libfaac MPEG version 要用 MPEG2 才能播 MPEG4 不行

最後結論

QuickTime 似乎
1.  只支援 AAC LC.
2. AAC 播放的話 只能播放 MPEG-2 Profile 的 AAC
3. 要Mux 成MP4的話,要使用 MPEG-4 的AAC 及勾選 MPEG-4 Profile。

2010年5月4日 星期二

C++ 心得(無法用pointer存取父類別的 protected member)

在C++中 子類別如果想要存取父類別的函式、data member ( non-static member )
直接叫用就行。

但是如果是用pointer 存取的方式那就會導致 error C2248。