2014年9月28日 星期日

[1] 原生碼native code 是什麼

nativecode或稱為binarycode/bitcode是將程式編譯成instructionsets(assemblycode)
最簡單的例子就是windows下的C++exe檔執行時直接load進memory
相對於nativecode的則是

bytecode是將程式編譯成javabytecode/MSILJAVA、Flash程式就是這種型式
執行時需透過一個virtualmachine/runtime

說明nativecode編譯器以前,
讓我先解釋另一個名詞─p-code,
p-code的意思是「虛擬的可執行碼」,為什麼說是「虛擬的」呢?
因為p-code雖然是可執行碼,但卻不是由CPU直接執行的
(必須經由「解譯器」解譯後方可執行),
所以不算是「真正的」可執行碼,故稱之。

相對的,nativecode則是由CPU直接執行的可執行碼。
VB4.0以前的版本都一直將程式編譯成p-code,而由於p-code必須經由「解譯器」解譯後方可執行,
所以執行效能不及nativecode,為了改善這個缺點,VB5.0的新功能之一便是:將程式編譯成nativecode。
據微軟宣稱,由於使用了nativecode,VB5的程式平均要比VB4的程式快20倍以上。

2014年9月23日 星期二

[QT] 使用designer搭配stylesheet (CSS) 美化介面


QT的stylesheet用法可參考官網,大致和CSS同
http://qt-project.org/doc/qt-4.8/stylesheet-examples.html#customizing-a-qpushbutton-using-the-box-model

[1] 在designer中點選元件的stylesheet來作編輯

[2]  打開編輯樣式表,可使用上方的選項來快速產生代碼

[3] 再來介紹如何加入圖片
     1.新增資源找地方存檔(.qrc)
     2.新增前置字串,打上斜線(/),用來找.qrc檔的相對路徑,有資料夾就再加資料夾名
     3.接著就可以新增圖片檔到qrc裡囉
     4.加好之後,就可以從建好的資源檔中選取圖片產生代碼了


[4] 產生好的qrc檔須經過編譯成cpp檔並加入專案才能在畫面上看到,否則介面的.h檔內的stylesheet無法找到,一樣使用QT BIN資料夾下rcc.exe
    執行rcc image.qrc -o image.cpp

[QT] 使用QT5.2.0 designer 產生UI給C++使用

此方式使用designer 建立介面,當然QT creator也是可以
但因VS介面較熟悉所以只用designer 建立介面,不使用QT creator建專案,覺得彈性也比較大

[1] 開啟designer建立widget



[2] 拉好所需的介面,存成.ui檔
[3] 使用QT bin資料夾下的uic.exe 將ui檔編譯為h檔
      uic.exe ClientUI.ui -o ClientUI.h
[4]  將h檔拉進專案,需要注意的是,為方便之後可以繼續以designer修改介面,最好避免手動去修改h檔,uic.exe重編會覆蓋掉你修改過的,所以須小心,那怎麼比較好呢,個人是建立子類別來繼承此UI類別,把要另外加的layout/元件和signal/slot和需要的UI加在這裡,(應該也可以直接從new出來的父類別改)
[5] 在main裡new出介面

QWidget widget;       // widget  
ClientUI_Imp ui;      // .ui產生的類別

ui.setupUi(&widget);  // 設定介面
ui.initCustomGui();   // 另外自定的介面
ui.initconn();        // 另外自定的signal/slot

widget.show();        // 顯示介面

2014年9月14日 星期日

[C/C++] char* 和 char[] 使用差別

char *p = "abc"; // 指標宣告, "abc"這個陣列會放在記憶體的"常數區塊",不允許被修改
char q[] = {'a','b','c',0}; // 陣列宣告,同時給予初始值
char r[] = "abc"; // 陣列宣告, 此空間就放在堆疊上
q[0] = '!'; // q字串變成 "!bc"
r[0] = '!'; // r字串變成 "!bc"
*p = '!'; // 這在Unix系統上會造成Segmentation fault (core dumped)

#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

char * strcopy(char *dest, char *from)
{
    char *p = dest;
    while(*dest++ = *from++)
    ;
    return p;
}

char * strconcat(char *dest, char *from)
{
    char *p = dest;
    while(*dest) dest++;
    
    while(*dest++ = *from++)
    ;
    
    return p;
}

char * strrever(char *dest)
{
    char *p = dest;
    char *pt = dest;
    
    while(*dest) dest++;
    ; 
    for(--dest; pt < dest; pt++, dest--)   
    {
        *pt = *pt ^ *dest;
        *dest = *pt ^ *dest;
        *pt = *pt ^ *dest;   
    }
   
    return p;
}


int main()
{
   //char str1[]="123      ";           // dest須給足空間 否則會有問題
   //char *str1 = "123456789"           // error 指標已指定長數空間 不能更改其內容
   char *str1 = (char *)malloc(20);     // dest須給足空間 否則會有問題
   char *str2="abcdef";
   
   char *str3 = strcopy(str1, str2);
   
   cout << str1 <<endl;
   cout << str2 <<endl;
   cout << str3 <<endl;
   
   //strcat(str1, str2);
   char *str4 = strconcat(str1, "test");
   
   cout << str1 <<endl;
   cout << str2 <<endl;
   cout << str4 <<endl;
   
   char *str5 = strrever(str1);
   
   cout << str1 <<endl;
   cout << str2 <<endl;
   cout << str5 <<endl;
   
   return 0;
}