2012年4月25日 星期三

Apple Lossless Codec (ALAC)

Apple Lossless 已經open source 了, 是一個很好的選擇
試著build , Windows 的版本 很簡單 沒啥問題 只是如果用VS2010 以前的
要自己下載 stdint.h
stdint.h 是 C99 標準 可以在 http://code.google.com/p/msinttypes/ 下載

然後build MIPS 版本
會出現 error C2733: second C linkage of overloaded function 'wmemchr' not allowed

那是因為 stdint.h include wchar.h
而且加上 extern "C"


#ifdef __cplusplus
extern "C" {
#endif
#  include
#ifdef __cplusplus
}

因為 C 不能 第二次 link 到 overloaded function
所以會出現C2733 錯誤
而且Apple  Lossless Solution 把一些 .c 檔都當成 c++ (/TP) 來 compile

如果把那些  .c 檔用 c 的方式來compile 就不會出現 C2733
不過會出現奇怪錯誤 error C2054: expected '(' to follow 'inline'
那是因為 C 沒有 inline keyword 要用 __inline

2種改法都行

應該是 sdk 中的 wchar.h 有問題 跟 win32 的 wchar.h 不一樣
sdk 中的 wchar.h 好像有明顯錯誤

在win32 中 wchar.h

wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
都是用 extern "C++" 括起來
但是 standard sdk 中卻沒有(應該是錯誤)
如果修改,移出 extern "C" 然後把 wmemchr, wcschr, wcspbrk, wcsrchr, wcsstr
用 extern "C++" 括起來, 就可以過關

第三種改法
改 stdint.h , extern "C" 改成 extern "C++"

#ifdef __cplusplus
extern "C++" {
#endif
#  include
#ifdef __cplusplus
}




然後繼續編譯, Link 出現一些問題
0. Link subsystem specify WindowsCE
1. unresolved external symbol __security_check_cookie 使用 /GS- 即可 ( Buffer Security Check OFF )
2. memset... function 沒有
要Link coredll.lib 或 corelibc.lib
在此不能用 coredll.lib 因為沒有 startup function like mainACRTStartup 
也沒有 exit()

http://msdn.microsoft.com/en-us/library/ms859584.aspx

最後 編譯完的EXE 到 MIPS上跑
結果不能run 顯示 cannot find one of its component
不知道少了什麼
只好用 dependency walker
http://www.dependencywalker.com/
發現少了 msvcr90d.dll
解決方法之一 是把 compiler option /MDd 改成 /MTd
就ok了 ^^

http://msdn.microsoft.com/en-us/library/abx4dbyh(v=vs.80).aspx
http://blog.monkeypotion.net/gameprog/beginner/love-and-hate-between-msvc-and-crt


Exception
事情總是沒那麼簡單,alacConvert 實際上在MIPS run 時,出現了Exception
code 是 0x80000002  address 000124A8
怎麼看 exception code 呢
之前都沒仔細研究
後來查到有關的 2個 API  GetExceptionCode 跟 RaiseException


追到 Exception Code 的定義在 winbase.h 然後又定義在 winnt.h(WIN32) 或 ntstatus.h (ARM)



#define EXCEPTION_ACCESS_VIOLATION          STATUS_ACCESS_VIOLATION
#define EXCEPTION_DATATYPE_MISALIGNMENT     STATUS_DATATYPE_MISALIGNMENT
#define EXCEPTION_BREAKPOINT                STATUS_BREAKPOINT





最常見的是 
EXCEPTION_ACCESS_VIOLATION          0xC0000005
EXCEPTION_DATATYPE_MISALIGNMENT     0x80000002
這兩個


再來 alignment fault 可以用 __unaligned 來解決或者自己copy (byte by byte)

Address 的話, 產生 .map 檔跟 listing files來觀察即可

note: __unaligned 是Microsoft specific
在Linux 中, 用 get_unaligned() 和 put_unaligned() macro


The easiest way to avoid unaligned access is to use the get_unaligned() and
put_unaligned() macros provided by the  header file.


http://lwn.net/Articles/260456/

沒有留言: