環境: redhat 9, MySQL 5.1.32
需求: 使用 MySQL C API 挿入資料時中文有問題, 因為 mysql設置資料儲存為UTF-8
解決: 將big5字串轉成utf-8字串, 然後再將utf-8字串存成16進制再挿入MySQL
#include <iconv.h>
#include <string.h>
#include <errno.h>
#define USR_NAME_LEN 64
char user[USR_NAME_LEN]; //從檔案讀來的Big5字串會存在user
char wuser[2*sizeof(user)+2];
const char fromcode[] = "big5";
const char tocode[] = "utf-8";
iconv_t cd;
size_t in_size = sizeof(user);
char *inptr = user;
char out[2*USR_NAME_LEN+1];
size_t out_size = sizeof(out);
char *outptr = out;
if ((iconv_t)(-1) == (cd = iconv_open(tocode, fromcode))) {
printf("(%s)Failed to iconv_open %s to %s.\n",strerror(errno), fromcode, tocode);
exit(EXIT_FAILURE);
}
if ((size_t)(-1) == iconv(cd, &inptr, &in_size, &outptr, &out_size)) {
printf("Fail to convert characters to new code set.(%s)\n", strerror(errno));
exit(EXIT_FAILURE);
iconv_close(cd);
}
那麼使用MySQL C API便可insert中文資料了!
char sqlcmd[512];
mysql_hex_string(wuser, out, strlen(out) );
DataBase<mysql> dataBase("127.0.0.1", "root", "yourpassword", "dbname");
memset(sqlcmd, 0, sizeof sqlcmd);
sprintf(sqlcmd, "INSERT INTO tablename(username) VALUES(0x%s)"
,wuser);
dataBase << sqlcmd ;
libiconv 只有三個functions
iconv_t iconv_open (const char* tocode, const char* fromcode):開啟 libiconv。
size_t iconv (iconv_t cd, const char* * inbuf, size_t * inbytesleft, char* * outbuf, size_t * outbytesleft):執行轉碼。
int iconv_close (iconv_t cd):做完轉碼後關閉 libiconv。
環境: target =wince 5.0 , use VC 2005
問題.需求: 計算程式執行所需時間
解決: 使用 CTime, CTimeSpan, GetCurrentTime()
所需 header file為 atltime.h
CTime ct_start, ct_end;
CTimeSpan ts;
int seconds;
ct_start = CTime::GetCurrentTime();
... 想計算執行時間的程式碼 ...;
ct_end = CTime::GetCurrentTime();
ts = ct_end - ct_start;
seconds = ts.GetTotalSeconds(); //將執行時間換算成秒數
程式在wince上跑量出來的秒數不準, 會有變多的情況.
改用GetTickCount()解決.
GetTickCount返回從操作系統啟動到現在所經過(elapsed)的毫秒數,它的返回值是DWORD。
(WinCE SDK) DWORD在 windef.h裡定義 (windows.h會包含windef.h, 所以只要包含windows.h)
typedef unsigned long DWORD; 它能表示的最大值為2^32=4,294,967,295,而一天有24*60*60*1000=86,400,000ms, 所以4,294,967,295/86,400,000 = 49.71,所以若系統持續運行49.71天,這個數會overflow繞回到零。
sample code:
DWORD dwStart, dwStop;
dwStart = GetTickCount();
//計算執行時間的程式碼;
dwStop = GetTickCount();
cout << "程式執行時間:" << (dwStop - dwStart)/1000 << "秒\n"; 由於GetTickCount返回的型別是DWORD(以wince sdk裡即unsigned long), 所以我們計時最多也只能49.71天超過的話就overflow了。
以下的程式例子說明: 當dwA加1後即overflow繞回為0, 但是計算相差多少時(大數減小數)結果不會影響。可是如果相差4294967296之後 相減的結果便開始是錯誤的。
DWORD dwA, dwB, dwD, dwE, dwF;
dwA = 4294967295;
dwB = dwA + 1;
dwD = dwA + 4294967295;
dwE = dwA + 4294967296;
dwF = dwA + 4294967297;
cout<<"dwA=" << dwA <<"\n";
cout<<"dwB=" << dwB <<"\n";
cout<<"dwD=" << dwD <<"\n";
cout<<"dwB-dwA=" << dwB-dwA <<"\n";
cout<<"dwD-dwA=" << dwD-dwA <<"\n";
cout<<"dwE-dwA=" << dwE-dwA <<"\n";
cout<<"dwF-dwA=" << dwF-dwA <<"\n";
輸出結果:
dwA=4294967295
dwB=0
dwD=4294967294
dwB-dwA=1
dwD-dwA=4294967295 //相減的結果還是對的
dwE-dwA=0 //相減的結果超過4294967295 即overflow了
dwF-dwA=1 //overflow
環境:wince 5.0, vc2005
問題:
我有一個process(主程式) 開了一個thread(用來接收radius response的回應), 主程式呼叫ACE_Thread_Manager::instance()->wait();後, 主程式永遠無法結束!
解決:使用 WaitForSingleObject();
在主程式宣告 global 變數 HANDLE g_hEvent;
g_hEvent = CreateEvent(NULL, TRUE, TRUE, L"VMAX_THREAD_EVT");
ResetEvent(g_hEvent); // 先用ResetEvent()將其設成未觸發狀態
... spawn thread ...;
switch (WaitForSingleObject( g_hEvent, 30000)) //等待thread
{
case WAIT_OBJECT_0:
// The thread has terminated - do something
break;
case WAIT_TIMEOUT:
// The timeout has elapsed but the thread is still running
// do something appropriate for a timeout
break;
}
在處理回應的程式碼 (thread會執行的地方)
ResetEvent(g_hEvent);
... 處理 ...;
SetEvent(g_hEvent); //用SetEvent()觸發event , 主程式的process便可以繼續執行
######################################################
同步就是說 當兩個執行緒同時在跑的時候 A執行緒需要等B執行緒跑完之後才進行下個動作
或者是有一個資源(如網路,圖片,DC....)同時只能有一個執行緒在使用 其他必須要等他用完才能繼續動作
CreateEvent(NULL,TRUE,TRUE,"MY_THREAD_EVT");
第一個是安全設定 這個通常不需要設定他
第二個參數為是否手動設定unsigaled狀態
TRUE代表我們必須要使用ResetEvent()來將他變回未觸發狀態 否則我們無法再觸發他
FALSE的話 代表event觸發完之後 他會自動變回未觸發狀態 我們可以馬上再觸發
第三個參數是初始狀態 FALSE代表初始狀態為未觸發狀態 此時我們可以觸發他
第四個參數是我們所給的名字 以後可以透過這個名字來開啟這個handle 開啟法如下
HANDLE g_hOutEvent =
::OpenEvent(EVENT_ALL_ACCESS,FALSE,"MY_THREAD_EVT");
OpenEvent()是讓我們在其他行程(Process)中也能共享同一個event
接下來便是同步了 同步可以使用WaitForSingleObject()來達成
範例如下
// process A
void Run()
{
::ResetEvent(g_hEvent);
// 在這裡執行process A的工作
::SetEvent(g_hEvent);
}
// process B
void WaitTeminate()
{
// 等待Process A完成
::WaitForSingleObject(g_hOutEvent,INFINITE);
}
以上兩個行程A B 共用同一個event 且行程B已使用OpenEvent()開啟行程A的event
當A開始執行前 先用ResetEvent()將其設成未觸發狀態
之後行程B只要執行到WaitForSingleObject()便會開始等待
行程A執行完成之後 會用SetEvent()觸發event
接下來在行程B中的WaitForSingleObject()便可以離開等待狀態 繼續執行了
最後 event不用的時候 要將他關閉
| ::CloseHandle(g_hOutEvent); |
Reference from http://blog.yam.com/swwuyam/article/11418020
最新回應
文章分類
- $$$ 理財 $$$
- 心情~
- 吃喝玩樂
- 好文章
- 知識
- -->程式設計
- 電腦~ Windows ~
- C language
- Linux
- Thread_同步