• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 16, 文章 - 0, 評論 - 55, 引用 - 0
            數(shù)據(jù)加載中……

            跨平臺的鼠標(biāo)移動源代碼

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

            #ifdef WIN32
            #include < windows.h >
            #else
            #include < unistd.h >
            #include < X11/X.h >
            #include < X11/Xlib.h >
            #endif

            int main(int argc, char* argv[])
            {
            ??? char sx[10], sy[10];
            ??? int x, y;

            ??? if ( argc < 3 ) return 0;
            ??? strcpy(sx, argv[1]);
            ??? strcpy(sy, argv[2]);
            ??? x = atoi(sx);
            ??? y = atoi(sy);

            #ifdef WIN32
            ??? SetCursorPos(x, y);
            #else
            ??? Display *dpy;
            ??? Window rootwindow;

            ??? dpy = XOpenDisplay(NULL);
            ??? if ( ! dpy ) {
            ??? ??? printf("Couldn't open Xdisplay.\n");
            ??? ??? exit(1);
            ??? }
            ??? rootwindow = DefaultRootWindow(dpy);

            ??? XWarpPointer(dpy, rootwindow, rootwindow, 0, 0, 0, 0, x, y);

            ??? XCloseDisplay(dpy);
            #endif
            ??? return 0;
            }


            posted @ 2006-05-31 13:22 cyantree 閱讀(672) | 評論 (0)編輯 收藏

            跨平臺的INI處理源代碼

            // IniFile.h

            #ifndef INIFILE_H
            #define INIFILE_H

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

            #ifndef OWP_DONT_DEF_FALSE
            #ifndef FALSE
            #define FALSE 0
            #endif
            #endif

            #ifndef OWP_DONT_DEF_TRUE
            #ifndef TRUE
            #define TRUE 1
            #endif
            #endif

            #ifndef OWP_DONT_DEF_BOOL
            #ifndef BOOL
            #define BOOL unsigned int
            #endif
            #endif

            #ifndef OWP_DONT_DEF_CCHR
            #ifndef CCHR
            #define CCHR const char
            #endif
            #endif

            #ifndef OWP_DONT_DEF_UCHR
            #ifndef UCHR
            #define UCHR unsigned char
            #endif
            #endif

            #ifndef OWP_DONT_DEF_UCCHR
            #ifndef UCCHR
            #define UCCHR const unsigned char
            #endif
            #endif

            #ifndef OWP_DONT_DEF_UINT
            #ifndef UINT
            #define UINT unsigned int
            #endif
            #endif

            #ifndef OWP_DONT_DEF_WORD
            #ifndef WORD
            #define WORD unsigned short
            #endif
            #endif

            #ifdef LINUX /* Remove CR, on unix systems. */
            #define INI_REMOVE_CR
            #define DONT_HAVE_STRUPR
            #endif

            #define tpNULL 0
            #define tpSECTION 1
            #define tpKEYVALUE 2
            #define tpCOMMENT 3

            struct ENTRY
            {
            char Type;
            char *pText;
            struct ENTRY *pPrev;
            struct ENTRY *pNext;
            };

            typedef struct
            {
            struct ENTRY *pSec;
            struct ENTRY *pKey;
            char KeyText [128];
            char ValText [128];
            char Comment [255];
            } EFIND;

            /* Macros */
            #define ArePtrValid(Sec,Key,Val) ((Sec!=NULL)&&(Key!=NULL)&&(Val!=NULL))

            class CIniFile
            {
            public:
            CIniFile (void)
            ??{
            ????m_pEntry = NULL;
            ????m_pCurEntry = NULL;
            ????m_result [0] = 0;
            ????m_pIniFile = NULL;
            ??}

            ??~CIniFile (void)
            ??{
            ????FreeAllMem ();
            ??}

            BOOL OpenIniFile (CCHR *pFileName)
            ??{
            ????char Str [255];
            ????char *pStr;
            ????struct ENTRY *pEntry;
            ????
            ????FreeAllMem ();
            ????
            ????if (pFileName == NULL) { return FALSE; }
            ????if ((m_pIniFile = fopen (pFileName, "r")) == NULL) { return FALSE; }
            ????
            ????while (fgets (Str, 255, m_pIniFile) != NULL) {
            ??????pStr = strchr (Str, '\n');
            ??????if (pStr != NULL) { *pStr = 0; }
            ??????pEntry = MakeNewEntry ();
            ??????if (pEntry == NULL) { return FALSE; }
            ??????
            ??????#ifdef INI_REMOVE_CR
            ??????Len = strlen(Str);
            ??????if ( Len > 0 ) {
            ????????if ( Str[Len-1] == '\r' ) {
            ??????????Str[Len-1] = '\0';
            ????????}
            ??????}
            ??????#endif
            ??????
            ??????pEntry->pText = (char *)malloc (strlen (Str)+1);
            ??????if (pEntry->pText == NULL) {
            ????????FreeAllMem ();
            ????????return FALSE;
            ??????}
            ??????strcpy (pEntry->pText, Str);
            ??????pStr = strchr (Str,';');
            ??????if (pStr != NULL) { *pStr = 0; } /* Cut all comments */
            ??????if ( (strstr (Str, "[") > 0) && (strstr (Str, "]") > 0) ) /* Is Section */ {
            ????????pEntry->Type = tpSECTION;
            ??????} else {
            ????????if (strstr (Str, "=") > 0) {
            ??????????pEntry->Type = tpKEYVALUE;
            ????????} else {
            ??????????pEntry->Type = tpCOMMENT;
            ????????}
            ??????}
            ??????m_pCurEntry = pEntry;
            ????}
            ????fclose (m_pIniFile);
            ????m_pIniFile = NULL;
            ????return TRUE;
            ??}

            void CloseIniFile ()
            ??{
            ????FreeAllMem ();
            ????if (m_pIniFile != NULL) {
            ??????fclose (m_pIniFile);
            ??????m_pIniFile = NULL;
            ????}
            ??}

            bool WriteIniFile (CCHR *pFileName)
            ??{
            ????struct ENTRY *pEntry = m_pEntry;
            ????if (m_pIniFile != NULL) {
            ??????fclose (m_pIniFile);
            ????}
            ????if ((m_pIniFile = fopen (pFileName, "wb")) == NULL) {
            ??????FreeAllMem ();
            ??????return FALSE;
            ????}
            ????
            ????while (pEntry != NULL) {
            ??????if (pEntry->Type != tpNULL) {
            ??????#ifdef INI_REMOVE_CR
            ????????fprintf (m_pIniFile, "%s\n", pEntry->pText);
            ??????#else
            ????????fprintf (m_pIniFile, "%s\r\n", pEntry->pText);
            ??????#endif
            ??????}
            ??????pEntry = pEntry->pNext;
            ????}
            ????
            ????fclose (m_pIniFile);
            ????m_pIniFile = NULL;
            ????return TRUE;
            ??}
            ??
            ??bool??DeleteKey (CCHR *pSection, CCHR *pKey)
            ??{
            ????EFIND List;
            ????struct ENTRY *pPrev;
            ????struct ENTRY *pNext;
            ????
            ????if (FindKey (pSection, pKey, &List) == TRUE) {
            ??????pPrev = List.pKey->pPrev;
            ??????pNext = List.pKey->pNext;
            ??????if (pPrev) {
            ????????pPrev->pNext=pNext;
            ??????}
            ??????if (pNext) {
            ????????pNext->pPrev=pPrev;
            ??????}
            ??????FreeMem (List.pKey->pText);
            ??????FreeMem (List.pKey);
            ??????return TRUE;
            ????}
            ????return FALSE;
            ??}

            ??BOOL ReadBool (CCHR *pSection, CCHR *pKey, BOOL Default)
            ??{
            ????char Val [2] = {"0"};
            ????if (Default != 0) { Val [0] = '1'; }
            ????return (atoi (ReadString (pSection, pKey, Val))?1:0); /* Only allow 0 or 1 */
            ??}

            int ReadInt (CCHR *pSection, CCHR *pKey, int Default)
            ??{
            ????char Val [12];
            ????sprintf (Val,"%d", Default);
            ????return (atoi (ReadString (pSection, pKey, Val)));
            ??}

            double ReadDouble (CCHR *pSection, CCHR *pKey, double Default)
            ??{
            ????double Val;
            ????sprintf (m_result, "%1.10lE", Default);
            ????sscanf (ReadString (pSection, pKey, m_result), "%lE", &Val);
            ????return Val;
            ??}

            CCHR *ReadString (CCHR *pSection, CCHR *pKey, CCHR *pDefault)
            ??{
            ????EFIND List;
            ????if (ArePtrValid (pSection, pKey, pDefault) == FALSE) { return pDefault; }
            ????if (FindKey (pSection, pKey, &List) == TRUE) {
            ??????strcpy (m_result, List.ValText);
            ??????return m_result;
            ????}
            ????return pDefault;
            ??}

            void WriteBool (CCHR *pSection, CCHR *pKey, bool Value)
            ??{
            ????char Val [2] = {'0',0};
            ????if (Value != 0) { Val [0] = '1'; }
            ????WriteString (pSection, pKey, Val);
            ??}
            ??
            void WriteInt (CCHR *pSection, CCHR *pKey, int Value)
            ??{
            ????char Val [12]; /* 32bit maximum + sign + \0 */
            ????sprintf (Val, "%d", Value);
            ????WriteString (pSection, pKey, Val);
            ??}

            void WriteDouble (CCHR *pSection, CCHR *pKey, double Value)
            ??{
            ????char Val [32]; /* DDDDDDDDDDDDDDD+E308\0 */
            ????sprintf (Val, "%1.10lE", Value);
            ????WriteString (pSection, pKey, Val);
            ??}

            void WriteString (CCHR *pSection, CCHR *pKey, CCHR *pValue)
            ??{
            ????EFIND List;
            ????char Str [255];
            ????
            ????if (ArePtrValid (pSection, pKey, pValue) == FALSE) { return; }
            ????if (FindKey (pSection, pKey, &List) == TRUE) {
            ??????sprintf (Str, "%s=%s%s", List.KeyText, pValue, List.Comment);
            ??????FreeMem (List.pKey->pText);
            ??????List.pKey->pText = (char *)malloc (strlen (Str)+1);
            ??????strcpy (List.pKey->pText, Str);
            ????} else {
            ??????if ((List.pSec != NULL) && (List.pKey == NULL)) /* section exist, Key not */ {
            ????????AddKey (List.pSec, pKey, pValue);
            ??????} else {
            ????????AddSectionAndKey (pSection, pKey, pValue);
            ??????}
            ????}
            ??}

            protected:
            ??struct ENTRY *m_pEntry;
            ??struct ENTRY *m_pCurEntry;
            ??char m_result [255];
            ??FILE *m_pIniFile;
            ??
            ??void AddKey (struct ENTRY *pEntry, CCHR *pKey, CCHR *pValue)
            ??{
            ????char Text [255];
            ????sprintf (Text, "%s=%s", pKey, pValue);
            ????AddItemAt (pEntry, tpKEYVALUE, Text);
            ??}
            ??
            ??BOOL AddItem (char Type, CCHR *pText)
            ??{
            ????struct ENTRY *pEntry = MakeNewEntry ();
            ????if (pEntry == NULL) { return FALSE; }
            ????pEntry->Type = Type;
            ????pEntry->pText = (char*)malloc (strlen (pText) +1);
            ????if (pEntry->pText == NULL) {
            ??????free (pEntry);
            ??????return FALSE;
            ????}
            ????strcpy (pEntry->pText, pText);
            ????pEntry->pNext = NULL;
            ????if (m_pCurEntry != NULL) { m_pCurEntry->pNext = pEntry; }
            ????m_pCurEntry = pEntry;
            ????return TRUE;
            ??}
            ??
            ??bool AddItemAt (struct ENTRY *pEntryAt, char Mode, CCHR *pText)
            ??{
            ????struct ENTRY *pNewEntry;
            ????if (pEntryAt == NULL) { return FALSE; }
            ????pNewEntry = (struct ENTRY*) malloc (sizeof (ENTRY));
            ????if (pNewEntry == NULL) { return FALSE; }
            ????pNewEntry->pText = (char *) malloc (strlen (pText)+1);
            ????if (pNewEntry->pText == NULL) {
            ??????free (pNewEntry);
            ??????return FALSE;
            ????}
            ????strcpy (pNewEntry->pText, pText);
            ????if (pEntryAt->pNext == NULL) /* No following nodes. */ {
            ??????pEntryAt->pNext = pNewEntry;
            ??????pNewEntry->pNext = NULL;
            ????} else {
            ??????pNewEntry->pNext = pEntryAt->pNext;
            ??????pEntryAt->pNext = pNewEntry;
            ????}
            ????pNewEntry->pPrev = pEntryAt;
            ????pNewEntry->Type = Mode;
            ????return TRUE;
            ??}
            ??
            ??void FreeMem (void *pPtr)
            ??{
            ????if (pPtr != NULL) { free (pPtr); }
            ??}
            ??
            ??void FreeAllMem (void)
            ??{
            ????struct ENTRY *pEntry;
            ????struct ENTRY *pNextEntry;
            ????pEntry = m_pEntry;
            ????while (1) {
            ??????if (pEntry == NULL) { break; }
            ??????pNextEntry = pEntry->pNext;
            ??????FreeMem (pEntry->pText); /* Frees the pointer if not NULL */
            ??????FreeMem (pEntry);
            ??????pEntry = pNextEntry;
            ????}
            ????m_pEntry = NULL;
            ????m_pCurEntry = NULL;
            ??}
            ??
            ??bool FindKey (CCHR *pSection, CCHR *pKey, EFIND *pList)
            ??{
            ????char Search [130];
            ????char Found [130];
            ????char Text [255];
            ????char *pText;
            ????struct ENTRY *pEntry;
            ????pList->pSec = NULL;
            ????pList->pKey = NULL;
            ????pEntry = FindSection (pSection);
            ????if (pEntry == NULL) { return FALSE; }
            ????pList->pSec = pEntry;
            ????pList->KeyText[0] = 0;
            ????pList->ValText[0] = 0;
            ????pList->Comment[0] = 0;
            ????pEntry = pEntry->pNext;
            ????if (pEntry == NULL) { return FALSE; }
            ????sprintf (Search, "%s",pKey);
            ????strupr (Search);
            ????while (pEntry != NULL) {
            ??????if ((pEntry->Type == tpSECTION) || /* Stop after next section or EOF */
            ????????(pEntry->Type == tpNULL )) {
            ????????return FALSE;
            ??????}
            ??????if (pEntry->Type == tpKEYVALUE) {
            ????????strcpy (Text, pEntry->pText);
            ????????pText = strchr (Text, ';');
            ????????if (pText != NULL) {
            ??????????strcpy (pList->Comment, pText);
            ??????????*pText = 0;
            ????????}
            ????????pText = strchr (Text, '=');
            ????????if (pText != NULL) {
            ??????????*pText = 0;
            ??????????strcpy (pList->KeyText, Text);
            ??????????strcpy (Found, Text);
            ??????????*pText = '=';
            ??????????strupr (Found);
            ??????????/* printf ("%s,%s\n", Search, Found); */
            ??????????if (strcmp (Found,Search) == 0) {
            ????????????strcpy (pList->ValText, pText+1);
            ????????????pList->pKey = pEntry;
            ????????????return TRUE;
            ??????????}
            ????????}
            ??????}
            ??????pEntry = pEntry->pNext;
            ????}
            ????return NULL;
            ??}

            ??bool AddSectionAndKey (CCHR *pSection, CCHR *pKey, CCHR *pValue)
            ??{
            ????char Text [255];
            ????sprintf (Text, "[%s]", pSection);
            ????if (AddItem (tpSECTION, Text) == FALSE) { return FALSE; }
            ????sprintf (Text, "%s=%s", pKey, pValue);
            ????return AddItem (tpKEYVALUE, Text)? 1 : 0;
            ??}
            ??
            ??struct ENTRY *MakeNewEntry (void)
            ??{
            ????struct ENTRY *pEntry;
            ????pEntry = (struct ENTRY *)malloc (sizeof (ENTRY));
            ????if (pEntry == NULL) {
            ??????FreeAllMem ();
            ??????return NULL;
            ????}
            ????if (m_pEntry == NULL) {
            ??????m_pEntry = pEntry;
            ????}
            ????pEntry->Type = tpNULL;
            ????pEntry->pPrev = m_pCurEntry;
            ????pEntry->pNext = NULL;
            ????pEntry->pText = NULL;
            ????if (m_pCurEntry != NULL) {
            ??????m_pCurEntry->pNext = pEntry;
            ????}
            ????return pEntry;
            ??}
            ??
            ??struct ENTRY *FindSection (CCHR *pSection)
            ??{
            ????char Sec [130];
            ????char iSec [130];
            ????struct ENTRY *pEntry;
            ????sprintf (Sec, "[%s]", pSection);
            ????strupr (Sec);
            ????pEntry = m_pEntry; /* Get a pointer to the first Entry */
            ????while (pEntry != NULL) {
            ??????if (pEntry->Type == tpSECTION) {
            ????????strcpy (iSec, pEntry->pText);
            ????????strupr (iSec);
            ????????if (strcmp (Sec, iSec) == 0) {
            ??????????return pEntry;
            ????????}
            ??????}
            ??????pEntry = pEntry->pNext;
            ????}
            ????return NULL;
            ??}

            ??#ifdef DONT_HAVE_STRUPR
            ??/* DONT_HAVE_STRUPR is set when INI_REMOVE_CR is defined */
            ??void strupr( char *str )
            ??{
            ????// We dont check the ptr because the original also dont do it.
            ????while (*str != 0) {
            ??????if ( islower( *str ) ) {
            ????????*str = toupper( *str );
            ??????}
            ??????str++;
            ????}
            ??}
            ??#endif
            ??
            private:
            };

            #endif

            #ifdef INIFILE_TEST_THIS_FILE
            int main (void)
            {
            ??CIniFile iFile;
            ??printf ("Hello World\n");
            ??iFile.OpenIniFile ("Test.Ini");
            ??iFile.WriteString ("Test", "Name", "Value");
            ??iFile.WriteString ("Test", "Name", "OverWrittenValue");
            ??iFile.WriteString ("Test", "Port", "COM1");
            ??iFile.WriteString ("Test", "User", "James Brown jr.");
            ??iFile.WriteString ("Configuration", "eDriver", "MBM2.VXD");
            ??iFile.WriteString ("Configuration", "Wrap", "LPT.VXD");
            ??iFile.WriteInt ("IO-Port", "Com", 2);
            ??iFile.WriteBool ("IO-Port", "IsValid", 0);
            ??iFile.WriteDouble ("TheMoney", "TheMoney", 67892.00241);
            ??iFile.WriteInt ("Test" , "ToDelete", 1234);
            ??iFile.WriteIniFile ("Test.Ini");
            ??printf ("Key ToDelete created. Check ini file. Any key to continue");
            ??while (!kbhit());
            ??iFile.OpenIniFile ("Test.Ini");
            ??iFile.DeleteKey ("Test"?? , "ToDelete");
            ??iFile.WriteIniFile ("Test.Ini");
            ??printf ("[Test] Name = %s\n", iFile.ReadString ("Test", "Name", "NotFound"));
            ??printf ("[Test] Port = %s\n", iFile.ReadString ("Test", "Port", "NotFound"));
            ??printf ("[Test] User = %s\n", iFile.ReadString ("Test", "User", "NotFound"));
            ??printf ("[Configuration] eDriver = %s\n", iFile.ReadString ("Configuration", "eDriver", "NotFound"));
            ??printf ("[Configuration] Wrap = %s\n", iFile.ReadString ("Configuration", "Wrap", "NotFound"));
            ??printf ("[IO-Port] Com = %d\n", iFile.ReadInt ("IO-Port", "Com", 0));
            ??printf ("[IO-Port] IsValid = %d\n", iFile.ReadBool ("IO-Port", "IsValid", 0));
            ??printf ("[TheMoney] TheMoney = %1.10lf\n", iFile.ReadDouble ("TheMoney", "TheMoney", 111));
            ??iFile.CloseIniFile ();
            ??return 0;
            }
            #endif

            posted @ 2006-05-31 13:20 cyantree 閱讀(883) | 評論 (1)編輯 收藏

            跨平臺的線程代碼

            改編自fltk,添加了linux平臺下的Sleep實現(xiàn),只支持Windows和Linux,分別用vc和gcc編譯,代碼如下:

            1 //threads.h, LGPL
            2
            3 #ifndef Threads_H
            4 #define Threads_H
            5
            6 #ifdef WIN32
            7
            8 #include < windows.h >
            9 #include < process.h >
            10
            11 typedef unsigned long Fl_Thread;
            12
            13 static int fl_create_thread(Fl_Thread& t, void *(*f) (void *), void* p)
            14 {
            15 return t = (Fl_Thread)_beginthread((void( __cdecl * )( void * ))f, 0, p);
            16 }
            17
            18 #else
            19
            20 // Use POSIX threading...
            21 #include < pthread.h >
            22 #include < unistd.h >
            23
            24 typedef pthread_t Fl_Thread;
            25
            26 static int fl_create_thread(Fl_Thread& t, void *(*f) (void *), void* p)
            27 {
            28 return pthread_create((pthread_t*)&t, 0, f, p);
            29 }
            30
            31 static void Sleep(unsigned long dwMilliseconds)
            32 {
            33 usleep(dwMilliseconds * 1000);
            34 }
            35
            36 #endif
            37
            38 #endif // !Threads_h

            使用示例:

            1 #include "thread.h"
            2 ...
            3
            4 static Fl_Thread m_thread; // define
            5 ...
            6
            7 // thread create
            8 fl_create_thread(m_thread, thread_fun, 0);
            9 ...
            10
            11 static void* thread_fun(void *p)
            12 {
            13 while (1) {
            14 ...
            15 }
            16
            17 return 0;
            18 }

            posted @ 2006-05-16 16:46 cyantree 閱讀(927) | 評論 (1)編輯 收藏

            從編譯Linux kernel說開來

              編譯內(nèi)核的概念是linux最帥的地方,windows是不會提供操作系統(tǒng)的源代碼的,而linux則不然,操作系統(tǒng)的源代碼全部都是公開的。 對于發(fā)行版而言,比如rh9,debian,suse等,都提供編譯好的kernel供用戶使用,但是這樣的kernel未必是用戶需要的,這時就可以自 己對 kernel的源代碼進行編譯,然后替換掉原來的kernel。

              其實編譯kernel并不恐怖,只是一件很簡單的事情,就幾條 指令而已。/usr/src/linnux是kernel源代碼常用的放置目錄,進入此目錄,執(zhí)行make menuconfig,會出來一個圖形界面,里面是kernel的各種配置和選項,把自己喜歡的驅(qū)動和配置選上,不需要的去除即可。然后make dep,這是檢查新的配置是否正確和做一些初始化工作。然后就是make bzImage,這是真正開始編譯kernel,bzImage是編譯后的kernel文件名,可以為任意名字,只是一般會以bzImage、 zImage或vmlinuz之類為名。如果編譯成功會生成一個bzImage文件,這就是kernel了。系統(tǒng)啟動最主要的就是調(diào)用這個文件,里面包括 了文件系統(tǒng)、硬件驅(qū)動、網(wǎng)絡(luò)基礎(chǔ)、內(nèi)存管理、進程管理等,在/boot下面有一個bzImage或者vmlinuz之類的文件就是原有的kernel,只 要把編譯后的kernel文件(bzImage)替換掉就換成新的kernel了,或者用新名字復(fù)制到/boot下,再將grub或lilo的配置文件修 改一下,下次啟動系統(tǒng)的時候即可使用新的kernel。下面是make modules,這是編譯驅(qū)動,或者說叫模塊,在linux下驅(qū)動可以和kernel編譯在一起,也可以編譯成單獨的模塊文件,如果是第一種, kernel啟動的時候就會自動嘗試載入驅(qū)動,第二種則是需要的時候手工加載驅(qū)動,也可以手動卸載。這是windows沒有的功能,比如顯卡的驅(qū)動在 windows下不重新啟動系統(tǒng)是無法更新的,但在linux下卻可以。比如對顯卡做升級動作的時候其實就是在編譯module,并卸載舊驅(qū)動,加載新驅(qū) 動,整個步驟無需重啟系統(tǒng)。最后一步,就是make modules_install,這個步驟是在/lib/modules下面生成一個按照kernel版本號為格式的目錄,再將編譯好的modules復(fù) 制進去。kernel啟動的時候會通過這樣的路徑搜索modules文件,類似windows的system32目錄。

              寫了這么多, 很多沒玩過linux的人看了會很迷糊,但了解一些相關(guān)認(rèn)識還是很有趣的,因為這才是linux好玩的地方,一個隨便捏來捏去的操作系統(tǒng),可以滿足某些人 士的變態(tài)心理-_-# windows可以運行的硬件平臺很有限,因為不公開,而且尺寸也很大,linux卻因為可以自己編譯,所以支持幾乎所有的硬件平 臺,x86,cs51,avr,pda,手機,alpha,大型機等等。同時尺寸還很小,一般編譯一個可以運行到shell的系統(tǒng),只要4、5M的尺寸就 可以搞定。加一個x-window也就30M左右,這在windows是不可想象的。這都是kernel公開,可以手動編譯的好處和樂趣....
            ?

            2006-05-10 20:55 (根據(jù)聊天紀(jì)錄修改)

            posted @ 2006-05-10 21:10 cyantree 閱讀(1014) | 評論 (1)編輯 收藏

            FLTK簡介

              FLTK,如同其名字所表達的:The Fast Light Tool Kit,一個輕量級的GUI開發(fā)庫。但這輕量級并不代表功能的羸弱,相反,F(xiàn)LTK在具有基本的GUI功能之外,還擁有一些特殊的功能,比如跨平臺、內(nèi)置 OpenGL功能、速度更快、尺寸更小、協(xié)議寬松等。當(dāng)然,缺點也是有的,比如對于復(fù)雜的界面構(gòu)件支持不夠,資源支持的不足等。但一個工具如果使用的好, 取其長而去其短,自然可以飛花摘葉皆可傷人;P

               我選擇FLTK 的過程還是比較曲折的,當(dāng)初做ARM下的GUI開發(fā),選擇的GUI庫是MiniGUI,一個國內(nèi)開發(fā)的界面庫。當(dāng)時還支持類unix平臺,對 Windows的支持尚在開發(fā)中。由于需要尋找一些問題的解答,所以經(jīng)常在其論壇上搜索,從而知道了還有microwindow、nano、 qtembedded等嵌入型GUI開發(fā)庫,但當(dāng)時沒有太過注意。后來又開始轉(zhuǎn)向WINCE平臺的開發(fā),這一擱就是2年。再后來終于要做跨平臺的開發(fā),對 具有跨平臺的GUI開發(fā)庫開始注意起來。

              一開始的選擇是wxWidgets,但是研究了一段時間后發(fā)現(xiàn)不好解決的問題越來越多,終于 放棄。最頭疼的就是C++類的事件傳遞,wxWidgets內(nèi)部使用的是一個類似MFC的方法,所有傳遞事件的類全部要從一個根類繼承,這樣就導(dǎo)致創(chuàng)建的 類和wxWidgets綁定過甚,復(fù)用性大大降低,同時由于wxWidgets的目標(biāo)不僅僅是GUI,造成其包含功能過多,其內(nèi)部結(jié)構(gòu)非常復(fù)雜,雖然是 OpenSource,但要若要修改其代碼還是很困難的。綜上所述,wxWidgets并不符合我的要求,從而被排除在外。

              之后研究的QT,老牌的跨平臺GUI開發(fā)庫,工具很多,開發(fā)也很人性化,qtdesign很像Delphi的界面開發(fā)方式,代碼帶有強烈的linux風(fēng)格,但是看看附帶的庫文件又實在讓人有些泄氣,尺寸大,發(fā)布麻煩。所以在試用了一段時間后還是放棄了。

               在此期間,其實也看到過一些對FLTK的介紹,但大多數(shù)對其評價不高,也就沒有注意。直到有一次偶然心血來潮,上http: //www.fltk.org看了一下,發(fā)現(xiàn)FLTK 似乎正對我的胃口,這才開始對其進行了深入的研究。經(jīng)過一段時間的實際開發(fā),個人覺得,對于跨平臺和代碼簡潔而言,F(xiàn)LTK是再適合不過了。

               FLTK的底層只提供一套完整的畫點、畫線功能,另外附帶了字體的顯示功能,但FLTK對字體的支持還很粗糙,尤其對于非英文字符集而言,后面我會詳細(xì) 說明。在基本的點、線功能基礎(chǔ)上,F(xiàn)LTK完全自己實現(xiàn)了一套界面,比如Button、Label、Edit、Tab等,全部都是由基本的點線畫出。看到 這,可能你會覺得這實在是屬于自己造輪子,吃力不討好。誠然,如果你只針對一種平臺開發(fā),這樣的做法不能帶來多少好處,還造成學(xué)習(xí)時間的拉長。但若要針對 多個平臺開發(fā),這樣做的好處就很明顯了。首先是移植容易,只要針對目標(biāo)平臺實現(xiàn)基本的點線功能就可以實現(xiàn)代碼的移植,這可能是所有跨平臺GUI庫中最方便 最直接的方案,目前FTLK支持MacOS、Windows、Linux(x-window)等平臺,針對WinCE(主要是unicode的問題)和 plam 的開發(fā)正在進行中。其次是保持了界面的一致性,雖然QT、GTK等開發(fā)庫也具有這種功能,但是他們都需要一套基本庫的支持,無法做到系統(tǒng)尺寸的優(yōu)化,而對 于FLTK而言,這卻恰恰是他的優(yōu)點和長項。最后是代碼層次清楚、結(jié)構(gòu)簡單,由于大部分的工作就是基于底層的點線功能進行自繪,所有很多代碼都是簡潔明 了,很少費話。

              底層之上是一套以Fl_開頭的類,代表了各種GUI構(gòu)件,比如Fl_Window、Fl_Button、 Fl_Input等,使用起來很是容易。同時由于上面所說的,所有的界面構(gòu)件都是畫出來的,因此在熟悉了這種方式后,生成自己的構(gòu)件也是很容易的,反正是 畫界面嘛,既然別人能做到,你也能做到,實在不行可以查閱源代碼進行學(xué)習(xí)。這些界面類的共同特點是輕量型、都擁有一個draw(),只要在draw()里 實現(xiàn)自己的繪畫動作即可。

              說到界面就不能不說其事件實現(xiàn)方式,對于FLTK而言,使用的是最直接的方法:while(1){}。這也 是很多人批評FLTK原始的一個原因。但仔細(xì)想想,其實這是最直接的辦法,不管是哪種平臺,最終的事件方案不外乎是死循環(huán)和中斷,中斷的確具有很多好處, 但只要while(1)能完成這部分的功能,那又有什么關(guān)系呢。每個界面類都有一個handle(int event),只要繼承這個成員函數(shù),就可以在其中處理自己的事務(wù)。是不是很簡單?同時由于這樣的事件方式,造成FLTK的刷新速度很快,事件反應(yīng)迅速, 也算是個附帶優(yōu)點了。現(xiàn)在大多數(shù)的開發(fā)庫都是采用OO方式的事件處理方式,但FLTK卻采用了最原始的函數(shù)指針方式,也算是一個異類,這可能和FLTK的 unix背景有關(guān),無論如何,這種方式還是需要一定的適應(yīng)時間的,而且這種方式的優(yōu)缺點也是屬于各花入各眼了,不過我本人還是很喜歡這種方式的,誰叫我比 較原始呢#-_-

              FLTK產(chǎn)生于NeXT環(huán)境,發(fā)展于X-window環(huán)境,所以對圖形加速的支持必然是選擇OpenGL。FLTK 使用Fl_Gl_Window這個類將OpenGL的基本功能囊括其中,只要在Fl_Gl_Window的draw()里glbegin/glend即 可,基本的設(shè)置工作FLTK全都做好了,對于我現(xiàn)在的系統(tǒng)要求簡直是最適合不過了。

              FLTK基于LGPL,對使用者的要求非常寬松: Contrary to popular belief, it can be used in commercial software - even Bill Gates could use it! 所以開發(fā)者不需要擔(dān)心其項目的隱形問題。但是如果對FLTK進行了卓有成效的修正最好還是能回饋給開發(fā)組,所謂我為人人,人人為我嘛。

               說了一堆的好話,現(xiàn)在開始談?wù)凢LTK的缺點。首先一條就是對非英文字體特別是中文的支持比較差,甚至是非常差。在Windows平臺下還好一點,因為 在 Windows平臺下使用的是TextOut函數(shù)輸出字符串,但是在X-Window環(huán)境下就完蛋了,無法正確顯示中文,也不能調(diào)用輸入法進行輸入。從這 點來說,F(xiàn)LTK還是只適合一些封閉軟件的開發(fā),對于通用軟件而言FLTK并非是一個好的選擇。但只能在Windows平臺下開發(fā)中文軟件也不是個辦法, 要解決中文的顯示問題也不難,目前FTLK的穩(wěn)定版是1.1.7,開發(fā)版是2.0,有人針對1.xx版本修改了一個unicode版本,可以很平滑的支持 漢字的顯示,但很遺憾,我沒有編譯成功過,如果誰編譯成功了可以給我來個信。2.0已經(jīng)對非英文的支持進行了專門的開發(fā),但目前還沒有release,在 不久的將來應(yīng)該可以完整的解決這個問題。目前,要么等待,要么就像我這樣,用點陣字庫瞞天過海。具體方法因為還不夠成熟,就不公布了。

              無論如何,F(xiàn)LTK的目標(biāo)還是針對嵌入式和封閉軟件的開發(fā),所以復(fù)雜的界面并非其長項,如果想做出花哨復(fù)雜的界面,還是用其他GUI庫比較好,F(xiàn)LTK并不適合。

              綜上所述,F(xiàn)LTK的優(yōu)點和缺點都是非常的突出,如何取舍還是自己決定吧。



            2006-04-16 22:02

            posted @ 2006-04-16 22:11 cyantree 閱讀(20567) | 評論 (20)編輯 收藏

            多進程的構(gòu)架方法

              做了4、5年的開發(fā),大大小小的項目也做了不少,但以前都有一個致命的問題,不知不覺就會寫出一個巨大的主程序出來,層次復(fù)雜,編碼痛苦,調(diào)試?yán)щy。但似乎大家都認(rèn)同這樣的開發(fā)方式,雖然都知道界面和功能分離是好事情,但就是做不到。我自己也曾痛苦的思考過,但沒有什么收效,似乎在Windows下的開發(fā)只能是這么痛苦。

              一星期前買了<<unix編程藝術(shù)>>,這一周可謂改天換地,每天都在閱讀和思考中度過,想必武俠小說中的武功大進也就是這個意思了。雖然書還沒看完,但是有些話實在是不吐不快。

               什么是界面?界面就是功能的子集。沒有哪個界面能反映所有的功能,但是若沒有界面,對于最終用戶來說又是不可忍受的,無論如何都不能指望讓一個門衛(wèi)學(xué)會輸入復(fù)雜的命令來完成工作,雖然最終用戶也包括專業(yè)人士,但這世界上終究普通人更多。在這樣的前提下,可以認(rèn)為功能永遠比界面更寬泛,更有適應(yīng)性,而GUI更狹窄,更具有特殊性,所以將界面和功能進行分拆也就成為一種必然趨勢。

              但是如何分拆?在Windows的世界里,一個普遍觀點就是DLL。DLL很好,但是還不夠好,因為無法直接使用、調(diào)試以及升級,帶來的問題遠比好處多。另一種方法就是在代碼級進行分層,比如GUI一層,功能一層,再用膠合層將二者整合。且不論膠合層的不可復(fù)用和調(diào)試?yán)щy,就一條,如何能做到GUI崩潰的時候卻不影響功能的實現(xiàn)?以前我做過的項目都是這樣處理的,直接的后果就是項目越到后期問題越多,代碼越不接受變化。調(diào)試花費了大量的人力物力,收效卻未必好,功能的一點點小修改就會造成代碼里出現(xiàn)意大利面條。你可以說只要前期的小心規(guī)劃和仔細(xì)架構(gòu)就能避免這些問題,但是誰能準(zhǔn)確預(yù)測未來?無論做怎樣的努力,你也不能保證現(xiàn)在的功能永遠不變,永遠不變的恰恰就是變。如果不能保持實現(xiàn)的穩(wěn)定性和較好的移植性,這樣的項目下場一般都不太好。

              說了這么多廢話,還是趕緊進入正題。談?wù)勥@一周來的心得體會!

              首先,變化是漸進的,非突變式的。如果能將變化的所在約束在一個比較小的代碼范圍內(nèi),修改就不會成為噩夢。怎么約束?就一個要求:在保證完整性的條件下讓每個模塊包含的功能盡量單一和足夠小。首先是保證完整性,不是代碼足夠短,包含的實現(xiàn)足夠少就是完整,要達到完整,就要讓模塊的各個部分做到不可分割和無需添加,按照古人的說法,就是增一分則太多,減一分則太少。這個要求雖然看起來很好理解,其實并沒有什么標(biāo)準(zhǔn)答案,每個人心里都有自己的回答,正所謂仁者見仁,智者見智。其次是單一化和小型化,一般來說,范圍太大的東西會造成人腦覆蓋不全,比如一個功能,如果牽扯的部分過多,就會造成從底層到中間層,再到上層,全部都要思考到,估計沒有幾個人能做到,即使做到了,將來的維護和修改也會變成噩夢。相反,只要功能的涉及面夠窄,就很容易進行思考和修改,這個道理應(yīng)該沒有什么問題。

              既然要保證模塊單一、小型化和保證完整,也就意味著這個模塊可以認(rèn)為是一個完整而單獨的程序,無需外圍程序的支持就可以單獨運行和測試。從而引出我的最重要的觀點:盡量用多進程來分拆程序。在Windows的世界里,多進程似乎是天生被忽略和鄙視的,從unix的觀點看,其主要原因是Windows的設(shè)計中對進程的快速創(chuàng)建支持不夠,造成對多進程的天然排斥和害怕。但是換一個思路看,多進程也許是目前最好的架構(gòu)方式。底層的功能分拆成各個進程單獨運行,通過ipc和上層的GUI進行交互,膠合層薄了,移植性增強了,調(diào)試容易了,功能演進也不再成為噩夢。需求永遠是漸變的,所以進程的漸變也就成為可控的行為。

            ?  多進程間的傳遞方式一般有這么幾種:共享內(nèi)存,管道(pipe),信號,消息, socket。其中共享內(nèi)存適宜于大量數(shù)據(jù)的即時傳遞,速度快,容量大。但使用共享內(nèi)存時需要仔細(xì)考慮讀寫沖突問題,一般的解決辦法是用全局鎖,但是鎖的存在必然會造成效率的下降,所以能不用鎖就盡量不要用。pipe的速度和容量都沒有共享內(nèi)存好,但是用來傳遞命令和返回值還是很適合的。信號和消息的方式一般會和操作系統(tǒng)聯(lián)系緊密,個人不太喜歡。最后是socket,對于異地交互而言,socket是目前很常用的手段,甚至本地進程間通訊也可以使用。但是由于和網(wǎng)絡(luò)有關(guān),所以同步性不好保證,需要辯證的使用。

              說了這么多,舉個例子說明一下。假設(shè)現(xiàn)在要做一套點菜軟件供酒店使用,其基本功能包括人員管理,桌臺管理,點菜管理,結(jié)賬以及后臺管理五個功能模塊。按照單進程的方式就是將所有功能整合在一起,系統(tǒng)啟動時加載所有的功能,一旦某個模塊出現(xiàn)問題,則必須重新啟動程序,而且各個模塊之間很容易發(fā)生資源沖突和請求沖突。如果換成多進程方式,讓我們看看有什么不同。首先是所有的功能最終目的地都是數(shù)據(jù)庫,那么可以開發(fā)一個后臺進程專門所有負(fù)責(zé)針對數(shù)據(jù)庫的請求,通過pipe或者共享內(nèi)存來接收命令和返回結(jié)果,那么程序或者說具體代碼塊之間的接口就是單一的pipe或共享內(nèi)存了。同時,即使某一個程序運行錯誤也不會造成整體失敗,只需要重起失敗的部分即可。當(dāng)然了,這種方式下存在一個問題,就是效率的降低,但是對于大多數(shù)的應(yīng)用來說,穩(wěn)定性的提高遠比效率的降低要重要,而且隨著硬件水平的不斷提高,效率總是可以達標(biāo)的。

              數(shù)據(jù)庫處理分拆出去后,剩下的就很好處理了,人員、點菜、桌臺等管理模塊都作為單獨的后臺程序出現(xiàn),最后GUI部分只需要和各個共享內(nèi)存和pipe打交道即可,無需只要具體的邏輯處理和功能實現(xiàn),而且各個后臺程序還可以復(fù)用,比如人員管理可以挪到客房服務(wù)系統(tǒng)中,甚至是其他系統(tǒng)。GUI隨時可以替換,實現(xiàn)了功能和界面的分離,同時系統(tǒng)崩潰的幾率大大降低,升級和售后也方便很多,永遠不要把最終用戶想的太愚蠢,很多時候人們還是蠻有求知欲的。

              更多的細(xì)節(jié)需要自己整理,這里只是給出了一個框架,起碼我現(xiàn)在的項目已經(jīng)開始這樣做,效果嘛,半年后就知道了。?

            2006-04-05 21:38?

            修改于2006-04-07 18:56

            再次修改于2006-04-13 21:55

            posted @ 2006-04-14 01:10 cyantree 閱讀(3213) | 評論 (12)編輯 收藏

            僅列出標(biāo)題
            共2頁: 1 2 
            夜夜亚洲天天久久| 亚洲人成无码久久电影网站| 亚洲AV日韩精品久久久久久| 综合网日日天干夜夜久久| 午夜久久久久久禁播电影| 精品视频久久久久| 狠狠色丁香久久婷婷综合_中| 久久99精品久久久久久久不卡| 国产真实乱对白精彩久久| 精品无码久久久久国产动漫3d| 国产成人综合久久精品尤物| 午夜精品久久久久9999高清| 国产三级久久久精品麻豆三级| 麻豆一区二区99久久久久| 青青青青久久精品国产h久久精品五福影院1421 | 久久婷婷五月综合色高清| 久久精品毛片免费观看| 亚洲精品无码久久久| www.久久热| 亚洲中文久久精品无码| 久久精品成人免费国产片小草| 国产亚洲美女精品久久久2020| 精品久久人人妻人人做精品| 久久99国产综合精品女同| 国产欧美久久久精品影院| 色综合久久久久| 99久久精品国产麻豆| 一本一本久久aa综合精品| 亚洲国产高清精品线久久| 精品久久综合1区2区3区激情| 久久成人国产精品二三区| 国内精品久久久久影院日本| 亚洲AV日韩精品久久久久| 久久精品国产乱子伦| 国产精品久久久久蜜芽| 欧美色综合久久久久久| 久久AAAA片一区二区| 久久成人18免费网站| 久久久青草青青国产亚洲免观| 久久99热这里只有精品国产 | 国内精品伊人久久久影院|