September 4,2008
以 Visual Studio 2005 編譯 boost::regex
下載 boost 跟 bjam 以後,第一件事情是編譯。
在使用時,在專案屬性裡指定 [組態屬性][C/C++][一般] 的 "其他Include目錄" 為 c:\boost_1_36_0,再指定 [組態屬性][連結器][一般] 的 "其他程式庫目錄" 為 "c:\boost_1_36_0\build\boost\bin.v2\libs\regex\build\msvc-8.0\debug\link-static\threading-multi",進行編譯即可。
- 打開 visual studio 2005 命令提示字元
- 切換到你的 boost目錄 下,這裡假設為 c:\boost_1_36_0
- 執行 bjam --build-dir="c:\boost_1_36_0\build" --toolset=msvc-8.0 --build-type=complete --with-regex stage,就可以只編譯 boost::regex.
- 編譯會需要一陣子,編譯好的檔案就會放在 c:\boost_1_36_0\build\boost\bin.v2\libs\regex\ 下
在使用時,在專案屬性裡指定 [組態屬性][C/C++][一般] 的 "其他Include目錄" 為 c:\boost_1_36_0,再指定 [組態屬性][連結器][一般] 的 "其他程式庫目錄" 為 "c:\boost_1_36_0\build\boost\bin.v2\libs\regex\build\msvc-8.0\debug\link-static\threading-multi",進行編譯即可。
May 9,2006
new之後,constructor之前
昨天在代碼裡面看到一個從沒看過的用法,如下列紅色標示部份:
以執行的結果來說,我實在是分辨不出來 (1) 與 (2) 有甚麼分別。
後來我用 gcc -S 去分別產生組合語言碼,總算是大致猜到了,原來以 (1) 的方法來寫,會把 new 以後的結果也複製到 myclass_mem 這個陣列裡面。 所以加上輸出 myclass_mem 內容的程式碼,再分別產生執行檔來看執行結果就很清楚了。 真是特別。
#include <iostream>
class MyBase {
protected:
int _id;
public:
MyBase():_id(0) {}
MyBase( int id ):_id(id) {}
int getId() {return _id; }
};
class MyClass: public MyBase {
public:
MyClass() {}
MyClass( int id ):MyBase( id ) {}
};
int myclass_mem[ sizeof(MyClass)/sizeof(int) ];
using namespace std;
MyBase* test()
{
return new (myclass_mem)MyClass( 100 );// 這裡 (1)
//return new MyClass( 100 ); // (2)
}
int
main( int argc, char* argv[] )
{
int len = sizeof( myclass_mem );
cout << "The size of myclass_mem is " << len << endl;
cout << "content of myclass_mem" << endl;
for( int i=0; i<len; i++ )
cout << myclass_mem[i] << " ";
cout << endl;
MyBase* base = ::test();
cout << base->getId() << endl;
cout << "content of myclass_mem" << endl;
for( int i=0; i<len; i++ )
cout << myclass_mem[i] << " ";
cout << endl;
}
class MyBase {
protected:
int _id;
public:
MyBase():_id(0) {}
MyBase( int id ):_id(id) {}
int getId() {return _id; }
};
class MyClass: public MyBase {
public:
MyClass() {}
MyClass( int id ):MyBase( id ) {}
};
int myclass_mem[ sizeof(MyClass)/sizeof(int) ];
using namespace std;
MyBase* test()
{
return new (myclass_mem)MyClass( 100 );// 這裡 (1)
//return new MyClass( 100 ); // (2)
}
int
main( int argc, char* argv[] )
{
int len = sizeof( myclass_mem );
cout << "The size of myclass_mem is " << len << endl;
cout << "content of myclass_mem" << endl;
for( int i=0; i<len; i++ )
cout << myclass_mem[i] << " ";
cout << endl;
MyBase* base = ::test();
cout << base->getId() << endl;
cout << "content of myclass_mem" << endl;
for( int i=0; i<len; i++ )
cout << myclass_mem[i] << " ";
cout << endl;
}
以執行的結果來說,我實在是分辨不出來 (1) 與 (2) 有甚麼分別。
後來我用 gcc -S 去分別產生組合語言碼,總算是大致猜到了,原來以 (1) 的方法來寫,會把 new 以後的結果也複製到 myclass_mem 這個陣列裡面。 所以加上輸出 myclass_mem 內容的程式碼,再分別產生執行檔來看執行結果就很清楚了。 真是特別。
July 15,2005
Duff’s Device
在國二菜鳥忙裡偷閒看到這篇Duff’s Device.
這段 code, 真的很神奇
不過我必須承認,在看了它提供的參考網址以後,我不知道這段 code 在幹麼....
參考網址:
這段 code, 真的很神奇
register n = (count + 7) / 8; /* count > 0 assumed */
switch (count % 8)
{
case 0: do { *to = *from++;
case 7: *to = *from++;
case 6: *to = *from++;
case 5: *to = *from++;
case 4: *to = *from++;
case 3: *to = *from++;
case 2: *to = *from++;
case 1: *to = *from++;
} while (–n > 0);
}
不過我必須承認,在看了它提供的參考網址以後,我不知道這段 code 在幹麼....
參考網址:
July 2,2005
longjmp/setjmp
這是一組有趣的 api, 一般性的用法,是先使用 setjmp 設定 break point, 之後要跳回來的時候,就使用 longjmp.
所以,用法大概是這樣...
很簡單吧,應該也可以兜出 try ... catch ... finally 的用法.
下面是我大致的想法
之後再參考書看看吧... ^^
所以,用法大概是這樣...
#include <stdio.h>
#include <setjmp.h>
jmp_buf setjmp_buffer;
int
main( int argc, char* argv[] )
{
if( setjmp( setjmp_buffer ) == 0 )
{
// do something
printf("longjmp!!\n");
longjmp( setjmp_buffer, 1 ); // 用 0 的話, setjmp() 就會收到 0, 那麼可能會無窮回圈
}
else
{
// do something
printf("after longjmp.\n");
}
}
很簡單吧,應該也可以兜出 try ... catch ... finally 的用法.
下面是我大致的想法
int exception_id;
if( ( exception_id = setjmp( setjmp_buffer ) ) == 0 ) // try
{
// do something
longjmp( setjmp_buffer, 1 ); // throw
}
else
{
if( exception_id == 1 ) // catch( 1 )
{
}
if( exception_id == 2 ) // catch( 2 )
{
}
// ....
}
// 之後,就是 finally...
之後再參考書看看吧... ^^
March 10,2005
用 wprintf 輸出 string
wprintf() 要印一個 wchar 字串時,得特別使用 %ls,如果你用 %s, 那表示要印一個一般的 char 字串。
所以這樣會只印出 m
而這樣才會正確的印出 "music is wonderful!"
所以這樣會只印出 m
wchar_t* myString=L"music is wonderful!!";
wprintf( L"%s\n", myString );
而這樣才會正確的印出 "music is wonderful!"
wchar_t* myString=L"music is wonderful!!";
wprintf( L"%ls\n", myString );
January 4,2005
printf
神奇的用法....老實說....我以前的確不知道可以這樣用~~
三人行必有我師
#include <stdio.h>
int main()
{
int i;
i=23;
printf("%*s\n", i, "blah");
printf("%*s\n", i+1, "blah");
}
這樣就可以自由決定格式了....
我以前大概會先用字串去串出前面的格式字串吧~~
三人行必有我師
#include <stdio.h>
int main()
{
int i;
i=23;
printf("%*s\n", i, "blah");
printf("%*s\n", i+1, "blah");
}
這樣就可以自由決定格式了....
我以前大概會先用字串去串出前面的格式字串吧~~
May 14,2004
ltdl library
可以輸入 info libtool 找 Module loaders for libltdl 就可以得到不少資訊.
簡單說,就是可以製作能動態載入 module/plugin 的 library, 以 linux 來說,底層其實就是 dlopen, dlsym 這些函數
這個 library 其實是一個 wrapper, 跨了好幾個平台: BSD, Linux, Win32...
configure.in 中的設定
AC_LIBLTDL_CONVENIENCE
AC_SUBST(LTLINCL)
AC_SUBST(LIBLTDL)
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_CONFIG_SUBDIRS(libltdl)
Makefile.am 中的設定
SUBDIRS=libltdl
INCLUDES=$(LTDLINCL)
prog_LDFLAGS=-export-dynamic
prog_LDADD=$(LIBLTDL) "_dlopen" self "_dlopen" fxx.la
prog_DEPENDENCIES=$(LIBLTDL) fool.la
prog 指的是執行檔名稱
而 module/plugin 的 Makefile.am 設定
xxx_la_LDFLAGS=-module
函數蠻多的,可以直接從 ltdl.h 去找或參考 info
對於 Multi-Thread 也有支援.
簡單說,就是可以製作能動態載入 module/plugin 的 library, 以 linux 來說,底層其實就是 dlopen, dlsym 這些函數
這個 library 其實是一個 wrapper, 跨了好幾個平台: BSD, Linux, Win32...
configure.in 中的設定
AC_LIBLTDL_CONVENIENCE
AC_SUBST(LTLINCL)
AC_SUBST(LIBLTDL)
AC_LIBTOOL_DLOPEN
AC_PROG_LIBTOOL
AC_CONFIG_SUBDIRS(libltdl)
Makefile.am 中的設定
SUBDIRS=libltdl
INCLUDES=$(LTDLINCL)
prog_LDFLAGS=-export-dynamic
prog_LDADD=$(LIBLTDL) "_dlopen" self "_dlopen" fxx.la
prog_DEPENDENCIES=$(LIBLTDL) fool.la
prog 指的是執行檔名稱
而 module/plugin 的 Makefile.am 設定
xxx_la_LDFLAGS=-module
函數蠻多的,可以直接從 ltdl.h 去找或參考 info
對於 Multi-Thread 也有支援.
April 22,2004
Linux Timezone programming HOW-TO
以前在作 NAS (Network Attached Server) 的時候,因為要取得並設定時區,所以去找到的資料.
主要是參考這篇 The GNU C Library - Time Zone Functions.還有一些其他 Linux 程式的方式來解決.
不過 GNU C 的這個 timezone functions 似乎不太 work,我想可能是我不會用吧~~後來是改用 symbolic link 的方式來解決~~
以下用問答的方式來記述:
1.如何取得目前 timezone?
2.如何設定 timezone?
3.和 TZ Environment Variable 的關係
4.如何瀏覽 zone??
5.預設值??
主要是參考這篇 The GNU C Library - Time Zone Functions.還有一些其他 Linux 程式的方式來解決.
不過 GNU C 的這個 timezone functions 似乎不太 work,我想可能是我不會用吧~~後來是改用 symbolic link 的方式來解決~~
以下用問答的方式來記述:
1.如何取得目前 timezone?
在設計上,可以將 /etc/localtime symbolic link 到 /usr/share/zoneinfo 下的 zone file. 藉著取得真實路徑的函數readlink(),就可以得知是哪裡的 timezone.
2.如何設定 timezone?
同 1, 可以用 symbolic link 的方式來設定
3.和 TZ Environment Variable 的關係
如果有設定 TZ 環境變數,那麼 /etc/localtime 將會失效.
TZ 有特定格式,需要查一下,大多的 embedded system 都是直接利用 TZ 環境變數,而不使用 zone file.
4.如何瀏覽 zone??
可以直接開啟 /usr/share/zoneinfo/zone.tab 來取得列表.
此檔共有四欄: code, coordinates, TZ, comments.
照慣例,以 # 開始的該列為註解.
比較需要用到的兩個欄位: TZ 與 comments.
5.預設值??
預設值可以直接指向 /usr/share/zoneinfo/GreenWich 表示為格林威治標準時間
March 28,2004
向侯捷請問STL sort的問題
這是蠻久以前的事情了,那時候為了這個 sort 的問題,發 mail 向侯捷先生請教.雖然隔了很久才回覆我,不過心裡還是很感動~~也才知道自己的程式出了什麼錯.
回覆日期:2003年2月20日 上午 03:38
你的程式寫的邏輯不對。
> bool operator==( const myInt& l, const myInt& r) {
> bool operator>( const myInt& l, const myInt& r) {
> bool operator<( const myInt& l, const myInt& r) {
這三個都沒有完整判斷。sort 的時候,要求 class 需定義 operator<,
而 operator< 在什麼時候應該傳回 0, 什麼時候傳回 正值,什麼時候傳回負值,有一定的規則。
問題不是出在你指的地方,而在這裡。
-- jjhou
----- Original Message -----
寄件者: "晏仁"
收件者:
傳送日期: 2002年10月8日 PM 11:07
主旨: 請教 STL sort() 的問題
> Dear 侯sir:
>
> 冒昧請教,以下是程式,而問題在最後面~
>
> #include <iostream>
> #include <algorithm>
> #include <vector>
>
> using namespace std;
>
> class myInt {
> protected:
> int id;
> public:
> myInt():id(0) {};
> explicit myInt( int i ):id(i) {};
> myInt( const myInt& i ):id(i.id) { };
> int getId( void ) const {
> return id;
> }
> myInt& operator=( myInt& i) {
> id=i.id;
> return *this;
> }
> myInt& operator=( int i ) {
> id=i;
> return *this;
> }
> myInt& operator*() { return *this; }
> myInt* operator->() { return this; }
> friend bool operator==( const myInt& l, const myInt& r );
> friend bool operator<( const myInt& l, const myInt& r );
> friend bool operator>( const myInt& l, const myInt& r );
> };
>
> bool operator==( const myInt& l, const myInt& r) {
> if( l.getId() == r.getId() )
> return true;
> }
>
> bool operator>( const myInt& l, const myInt& r) {
> if( l.getId() > r.getId() )
> return true;
> }
> bool operator<( const myInt& l, const myInt& r) {
> if( l.getId() < r.getId() )
> return true;
> }
>
> class myIntCompare {
> public:
> int operator()( myInt aa, myInt bb ) {
> if( aa.getId() > bb.getId() )
> return 1;
> if( aa.getId() == bb.getId() )
> return 0;
> if( aa.getId() < bb.getId() )
> return -1;
> }
> };
>
> int
> main( int argc, char* argv[] ) {
> const int COUNTS=10000;
> typedef vector< myInt > intVector_t;
> intVector_t intVector;
> int i;
>
> /**
> * 下面的兩行 code 會導致 segmentation fault,這就是我要問的問題!!
> * for( i=COUNTS;i>=0;--i )
> * intVector.push_back( myInt(i) );
> */
> intVector.reserve( COUNTS );
> for( i=COUNTS; i>=0; --i )
> intVector[i]=i;
>
> // 以下兩種寫法都可以
> sort( intVector.begin(), intVector.end(), myIntCompare() );
> //sort( intVector.begin(), intVector.end() );
>
> for( i=0; i<=COUNTS; ++i )
> cout << intVector[i].getId() << endl;
> }
>
> 為什麼把
> intVector.reserve( COUNTS );
> for( i=COUNTS; i>=0; --i )
> intVector[i]=i;
>
> 改成
> for( i=COUNTS;i>=0;--i )
> intVector.push_back( myInt(i) );
>
> 編譯後再執行
> 就會發生 segmentation fault 的問題呢??
> 真的是很奇怪
> 我知道 vector 在配置的時候會先預留一塊記憶體
> 在 push_back() 的時候,如果發現不夠大,會自動重新配置,
> 並把原來的內容搬到新的地方去.
> 我想可能是重新配置的問題~~
> 但卻不知道真正的原因是什麼?
> 希望侯 sir 能給我一些方向,讓我下手去找出答案~
>
> 喔,對了,我的環境是 linux g++ 2.96.
>
> With Best Regards.
November 18,2003
gcc 的超強 Warning 選項
想不到
真是想不到
gcc 的 Warning 選項居然可以做到可以檢查你的 code 是不是用了 char, 還有 enumeration 內定義的所有數字是否都被用了
功能真是超強~
但是今天下午被這個玩意兒卡了快一個多小時
真是可惡~~
真是想不到
gcc 的 Warning 選項居然可以做到可以檢查你的 code 是不是用了 char, 還有 enumeration 內定義的所有數字是否都被用了
功能真是超強~
但是今天下午被這個玩意兒卡了快一個多小時
真是可惡~~