• <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>
            隨筆-91  評論-137  文章-0  trackbacks-0
             
            修正了return語句的一些Bug
            添加了COM組件的支持(見Samples目錄下的factorial.txt)

            ESEngine_Demo3.rar
            posted @ 2011-02-07 17:27 lwch 閱讀(1446) | 評論 (0)編輯 收藏
            1.首先我們必須知道C語言的調用約定為__cdecl(即參數從右向左依次進棧,由調用者還原堆棧).
            2.一條push指令最多壓入4個字節,當不足4個字節時應補齊4個字節,超過4個字節時應該由低位到高位依次壓棧.
            3.pop指令也和push一樣一次只能彈出4個字節.
            4.我們需要一個CallStruct類型來儲存一個參數.
             1 class CallStruct
             2     {
             3     public:
             4         INT            Integer;
             5         BOOL        Bool;
             6         DOUBLE        Real;
             7         WCHAR        String[MAX_STRING];
             8         
             9         enum TYPE
            10         {
            11             ctInteger,
            12             ctString,
            13             ctBool,
            14             ctReal,
            15             ctVoid,
            16         }Type;
            17         
            18         CallStruct() : Integer(0),Bool(FALSE),Real(0)
            19         {
            20             String[0]    = 0;
            21         }
            22 
            23         CallStruct(const NAutoPtr<VirtualMachine::VarClass>& Var) : Integer(Var->Integer),Bool(Var->Bool),Real(Var->Real),Type((TYPE)Var->Type)
            24         {
            25             if(Type == ctString) wcscpy(String,Var->String);
            26         }
            27     };
            5.我們需要一個列表來存放參數和一個返回值對象來存放返回值.
            1     List<NAutoPtr<CallStruct>> VarList;
            2     NAutoPtr<CallStruct> Return;
            6.最后我們需要一個HMODULE和一個FARPROC分別存放dll的句柄和函數地址.
            1     HMODULE hModule;
            2     FARPROC FunctionPtr;
            7.然后我們添加幾個功能函數.
            1     BOOL AddVar(NAutoPtr<VirtualMachine::VarClass>& Var);
            2     BOOL SetReturnType(CallStruct::TYPE Type);
            3     BOOL SetLibName(LPTSTR Name);
            4     BOOL SetFunctionName(LPTSTR Name);
            注意:GetProcAddress第二個參數只接受LPCSTR類型的字符串,應此如果傳入的是Unicode編碼的字符必須將其轉換成ANSI的.
            8.我們添加一個函數Run用于調用函數.
             1 BOOL CallMacro::Run()
             2 {
             3     if(FunctionPtr == 0 || Return.Buffer() == 0return FALSE;
             4     union RealStruct
             5     {
             6         double Real;
             7         struct
             8         {
             9             int Head,Tail;
            10         };
            11     };
            12     NAutoPtr<CallStruct> cs;
            13     int Integer;
            14     BOOL Bool;
            15     RealStruct Real; // Push指令一次只能壓入4字節
            16     LPTSTR String;
            17 
            18     int iEsp;
            19     __asm mov int ptr[iEsp],esp; // 保存esp
            20     for(int i=0;i<VarList.Size();i++)
            21     {
            22         cs = VarList[i];
            23         Integer = cs->Integer;
            24         Bool = cs->Bool;
            25         Real.Real = cs->Real;
            26         String = cs->String;
            27         switch(cs->Type)
            28         {
            29         case CallStruct::ctInteger:
            30             __asm push Integer;
            31             break;
            32         case CallStruct::ctString:
            33             __asm push String;
            34             break;
            35         case CallStruct::ctBool:
            36             __asm push Bool;
            37             break;
            38         case CallStruct::ctReal:
            39             __asm push Real.Tail;
            40             __asm push Real.Head;
            41             break;
            42         }
            43     }
            44     FARPROC proc = FunctionPtr;
            45     int Head,Tail;
            46     __asm
            47     {
            48         call proc
            49         mov int ptr[Head],edx
            50         mov int ptr[Tail],eax
            51     }
            52     switch(Return->Type)
            53     {
            54     case CallStruct::ctInteger:
            55         Return->Integer = Tail;
            56         break;
            57     case CallStruct::ctString:
            58         wcscpy(Return->String,(LPCTSTR)Tail);
            59         break;
            60     case CallStruct::ctBool:
            61         Return->Bool = Tail;
            62         break;
            63     case CallStruct::ctReal:
            64         __asm fstp [Real.Real];
            65         Return->Real = Real.Real;
            66         break;
            67     }
            68     // __declspec調用約定,需要手工還原堆棧
            69     __asm mov esp,int ptr[iEsp];
            70     return TRUE;
            71 }
            Run函數首先檢查是否已經裝載了DLL并獲得了函數地址,以及返回值類型是否已經定義.
            然后根據類型依次將函數壓棧.
            然后調用call指令并保存返回值.(這里需要注意的是當返回值類型為double或float類型時必須使用fstp指令從FPU寄存器棧的棧頂的值取出來)
            最后還原堆棧.

            然后我們來測試一下.
            創建一個名為TestDLL的DLL工程并添加函數Test.
            1 TESTDLL_API double Test(double d,double* d1,WCHAR* lpBuffer)
            2 {
            3     if(d == 123.456789) MessageBox(0,lpBuffer,L"",0);
            4     *d1 = 789.654;
            5     return 77777;
            6 }

            然后創建一個測試工程,添加相關文件.
            在_tmain中添加以下代碼.
             1 int _tmain(int argc, _TCHAR* argv[])
             2 {
             3     double d;
             4     CallMacro cm;
             5     NAutoPtr<VirtualMachine::VarClass> Var;
             6 
             7     Var = new VirtualMachine::VarClass;
             8     Var->Type = VirtualMachine::VarClass::vtString;
             9     wcscpy(Var->String,L"aaaaa");
            10     cm.AddVar(Var);
            11 
            12     Var = new VirtualMachine::VarClass;
            13     Var->Type = VirtualMachine::VarClass::vtInteger;
            14     Var->Integer = (INT)&d;
            15     cm.AddVar(Var);
            16 
            17     Var = new VirtualMachine::VarClass;
            18     Var->Type = VirtualMachine::VarClass::vtReal;
            19     Var->Real = 123.456789;
            20     cm.AddVar(Var);
            21 
            22     cm.SetLibName(L"TestDll.dll");
            23     cm.SetFunctionName(L"Test");
            24     cm.SetReturnType(CallMacro::CallStruct::ctReal);
            25     cm.Run();
            26 
            27     wprintf(L"%f %f\n",d,cm.Return->Real);
            28     system("pause");
            29     return 0;
            30 }

            編譯并運行,可以看到Test函數調用成功,并成功輸出d的值和返回值.

            最后給出完整代碼.
            posted @ 2011-02-06 22:21 lwch 閱讀(2650) | 評論 (0)編輯 收藏
            1.修正了函數調用時的一些Bug
            2.示例中增加了一個遞歸求階乘的例子

            ESEngine_Demo2.rar
            posted @ 2011-01-30 21:19 lwch 閱讀(1377) | 評論 (0)編輯 收藏

            運行方法:
            1.打開命令行提示符
            2.cd ESEngine.exe所在路徑
            3.ESEngine xxx.txt

            1.Samples文件夾下有幾個例子
            2.函數目前只寫了
              "function" "{Symbol}" "{LQ}" "{RQ}" stmt_list "end" "function"
              "function" "{Symbol}" "{LQ}" "{RQ}" "end" "function"
              "function" "{Symbol}" "{LQ}" paramter_list "{RQ}" "as" var_type stmt_list "end" "function"
              這三類,所以對于
              function mn(integer s)
             stmts
              end function
              在生成語法樹時會產生錯誤

            ESEngine_Demo1_0.rar

            posted @ 2011-01-28 21:03 lwch 閱讀(1233) | 評論 (0)編輯 收藏
            表達式:
            1 function main()
            2     integer a
            3     a = -(-+ -123 * +5 + -a)
            4 end function

            翻譯結果:


            表達式:
            1 function main()
            2     integer a
            3     a = -(-- -1)
            4 end function

            翻譯結果:
            posted @ 2011-01-27 21:39 lwch 閱讀(1225) | 評論 (1)編輯 收藏
            《面向組合子的一些測試》 進一步完善代碼,制作出詞法分析器.

            我們首先需要一個Fail基類,他有一個純虛函數Parser.
            1 class Fail
            2 {
            3 public:
            4     virtual NWString Parser(NWString& input)=0;
            5 };
            Parser的輸入為要分析的字符串,輸出為分析完成后剩余的字符串.

            然后我們需要一個Ch和一個Str分別用來分析單個字符和一個字符串.
             1 class Ch : public Fail
             2 {
             3 public:
             4     Ch(WCHAR _value) : value(_value){}
             5 
             6     NWString Parser(NWString& input);
             7 
             8     WCHAR Value();
             9 protected:
            10     WCHAR value; // 待匹配串
            11 };
            12 
            13 class Str : public Fail
            14 {
            15 public:
            16     Str(NWString _value) : value(_value){}
            17 
            18     NWString Parser(NWString& input);
            19 protected:
            20     NWString value; // 待匹配串
            21 };

            然后是Seq,Alt和Any,分別表示組合,選擇和循環.
             1 class Seq : public Fail
             2 {
             3 public:
             4     Seq(const NAutoPtr<Fail>& _left,const NAutoPtr<Fail>& _right) : left(_left),right(_right){}
             5 
             6     NWString Parser(NWString& input);
             7 protected:
             8     NAutoPtr<Fail> left;
             9     NAutoPtr<Fail> right;
            10 };
            11 
            12 class Alt : public Fail
            13 {
            14 public:
            15     Alt(const NAutoPtr<Fail>& _left,const NAutoPtr<Fail>& _right) : left(_left),right(_right){}
            16 
            17     NWString Parser(NWString& input);
            18 protected:
            19     NAutoPtr<Fail> left;
            20     NAutoPtr<Fail> right;
            21 };
            22 
            23 class Any : public Fail
            24 {
            25 public:
            26     Any(const NAutoPtr<Fail>& _left,const int _count) : left(_left),count(_count){}
            27 
            28     NWString Parser(NWString& input);
            29 protected:
            30     NAutoPtr<Fail> left;
            31     int count;
            32 };

            最后我們需要一個Node類型來存放以上這幾類對象.
             1 class Node
             2 {
             3 public:
             4     Node(){}
             5     Node(const NAutoPtr<Fail>& _left) : left(_left){}
             6 
             7     friend NAutoPtr<Node> operator+(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
             8     friend NAutoPtr<Node> operator|(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
             9     friend NAutoPtr<Node> operator-(const NAutoPtr<Node>& left,const NAutoPtr<Node>& right);
            10 
            11     static NAutoPtr<Node> OnceMore(NAutoPtr<Node> node);
            12     static NAutoPtr<Node> More(NAutoPtr<Node> node);
            13     static NAutoPtr<Node> NewCh(WCHAR input);
            14     static NAutoPtr<Node> NewStr(NWString input);
            15 
            16     NWString Parser(NWString& input);
            17 
            18     NAutoPtr<Fail>& Value();
            19 protected:
            20     NAutoPtr<Fail> left;
            21 };
            下面來分析一下Node里的函數:
            +:對應于Seq,用于將兩個Node連接起來.
            |:對應與Alt,用于選擇兩個Node.
            -:只有left和right的Value()都是NAutoPtr<Ch>時才可使用,內部有類型轉換,表示從哪個字符到哪個字符.
            OnceMore:重復1次及以上.
            More:重復0次以上.
            NewCh:生成一個NAutoPtr<Ch>的Node對象.
            NewStr:生成一個NAutoPtr<Str>的Node對象.

            下面我們需要4個宏.
            1 #define ONCEMORE(N)                    Node::OnceMore(N)
            2 #define MORE(N)                        Node::More(N)
            3 #define NEWCH(N)                    Node::NewCh(N)
            4 #define NEWSTR(N)                    Node::NewStr(N)
            這4個宏僅為了輸入方便

            然后我們來測試一下:
            1     NAutoPtr<Node> Symbol = ONCEMORE(NEWCH('_'| NEWCH('a'- NEWCH('z')) | (NEWCH('A'- NEWCH('Z'))
            2         + MORE(NEWCH('_'| (NEWCH('0'- NEWCH('9')) | (NEWCH('a'- NEWCH('z')) | (NEWCH('A'- NEWCH('Z')));
            3     NAutoPtr<Node> Number = ONCEMORE(NEWCH('0'- NEWCH('9'));
            4     NAutoPtr<Node> Real = Number + NEWCH('.'+ Number;
            相信對正則表達式有一定認識的同學已經知道這3條語句分別對應于什么正則表達式.
            Symbol->[_a-zA-Z]+[_0-9a-zA-Z]*
            Number->[0-9]+
            Real->[0-9]+.[0-9]+

            定義一個待分析的字符串.
            1     NWString str = L"abcce_fg123.459agetr";

            對其分析.
            1     wprintf(L"%s\n",str);
            2     wprintf(L"%s\n",Symbol->Parser(str));
            3     wprintf(L"%s\n",Real->Parser(str));
            4     wprintf(L"%s\n",Symbol->Parser(str));

            分析結果.
            1 abcce_fg123.459agetr
            2 123.459agetr
            3 agetr
            4 

            因為沒有考慮分析效率問題,所以使用NWString作為輸入和輸出,在實際使用中可用LPTSTR來代替NWString,同時修改響應代碼.
            最后給出源代碼
            posted @ 2011-01-26 22:11 lwch 閱讀(2433) | 評論 (9)編輯 收藏
                 摘要: 本文的思路來源于http://m.shnenglu.com/vczh/archive/2008/05/21/50656.html首先先看代碼:   1 #include <stdio.h>  2   3 class Element  4 {&n...  閱讀全文
            posted @ 2011-01-22 17:11 lwch 閱讀(1637) | 評論 (4)編輯 收藏
            下面來分析一下NScript的部分數據結構
             1     class SyntaxNode
             2     {
             3     public:
             4         int Op1;
             5         int Op2;
             6         List<NAutoPtr<SyntaxNode>> Child;
             7 
             8         SyntaxNode(int O1,int O2) : Op1(O1),Op2(O2){}
             9     };
            10 
            11     class CharClass
            12     {
            13     public:
            14         int Index;
            15         NWString String;
            16 
            17         CharClass(NWString S) : String(S){}
            18     };

            每個語法樹的節點有2個參數Op1,Op2分別表示當前節點的類型和附加參數
            Child為當前節點的子節點

            CharClass結構則比較簡單分別為索引和字符

            然后是部分SyntaxNode的Op1的枚舉:
            1     enum OpCode_Type
            2     {
            3         opNull,
            4         opVar,
            5         opConst,
            6     };

            以及VarType的枚舉:
             1     enum Var_Type
             2     {
             3         vtNull,
             4         vtVoid,
             5         vtBool,
             6         vtInt,
             7         vtReal,
             8         vtString,
             9         vtSymbol,
            10     };
            和產生式索引的宏定義:
             1     #define INDEX_VARTYPE_VOID                1
             2     #define INDEX_VARTYPE_BOOL                2
             3     #define INDEX_VARTYPE_INT                3
             4     #define INDEX_VARTYPE_REAL                4
             5     #define INDEX_VARTYPE_STRING            5
             6     #define INDEX_VALUETYPE_STRING            6
             7     #define INDEX_VALUETYPE_SYMBOL            7
             8     #define INDEX_VALUETYPE_REAL            8
             9     #define INDEX_VALUETYPE_DIGIT            9
            10     #define INDEX_VALUETYPE_TRUE            10
            11     #define INDEX_VALUETYPE_FALSE            11

            以上索引的定義取自NS.txt,隨著以后文法的增加這里的索引定義也會增加
            NS.h,NS.cpp,NS.ParserTable均是由NScriptMacro.exe運行NS.txt生成的

            下面來看一下SyntaxAnalyze函數:
             1 BOOL NSyntax::SyntaxAnalyze(int i)
             2 {
             3     BOOL bResult = TRUE;
             4     // 根據產生式索引生成語法樹
             5     switch(i)
             6     {
             7     case INDEX_VARTYPE_VOID:
             8     case INDEX_VARTYPE_BOOL:
             9     case INDEX_VARTYPE_INT:
            10     case INDEX_VARTYPE_REAL:
            11     case INDEX_VARTYPE_STRING:
            12         bResult = VarType(i);
            13         break;
            14     case INDEX_VALUETYPE_STRING:
            15     case INDEX_VALUETYPE_SYMBOL:
            16     case INDEX_VALUETYPE_REAL:
            17     case INDEX_VALUETYPE_DIGIT:
            18     case INDEX_VALUETYPE_TRUE:
            19     case INDEX_VALUETYPE_FALSE:
            20         bResult = ValueType(i);
            21         break;
            22     }
            23     return bResult;
            24 }

            這個函數根據傳入參數(產生式索引)調用相關函數生成語法樹,具體語法樹的生成過程請看相關代碼
            posted @ 2011-01-14 16:00 lwch 閱讀(1477) | 評論 (0)編輯 收藏
            項目地址

            最初文法定義為:
             1 %token "void" "bool" "int" "real" "string";
             2 %token "true" "false";
             3 %token "{" "}" "," ";" "=";
             4 %token "+" "-" "*" "/";
             5 %token ">" "<" ">=" "<=" "==" "and" "not" "or";
             6 
             7 %start program;
             8 
             9 var_type    ->    "void"
            10             |    "bool"
            11             |    "int"
            12             |    "real"
            13             |    "string"
            14             ;
            15 
            16 value_type    ->    "{String}"
            17             |    "{Symbol}"
            18             |    "{real}"
            19             |    "{digit}"
            20             |    "true"
            21             |    "false"
            22             ;
            23 
            24 paramter_define_desc    ->    "{LQ}" paramter_defines "{RQ}"
            25                         |    "{LQ}" "{RQ}"
            26                         ;
            27 
            28 paramter_defines    ->    paramter_defines "," paramter_one
            29                     |    paramter_one
            30                     ;
            31 
            32 paramter_one        ->    var_type "{Symbol}"
            33                     ;
            34 
            35 assign_type            ->    "{Symbol}"
            36                     ;
            37 
            38 program        ->    item_list
            39             ;
            40 
            41 item_list    ->    item_list item
            42             |    item
            43             ;
            44 
            45 item        ->    function
            46             |    define_desc ";"
            47             ;
            48 
            49 stmt_list    ->    stmt_list stmt
            50             |    stmt
            51             ;
            52 
            53 stmt        ->    define_desc ";"
            54             |    assign_desc ";"
            55             |    ";"
            56             ;
            57 
            58 function    ->    var_type "{Symbol}" paramter_define_desc "{" stmt_list "}"
            59             |    var_type "{Symbol}" paramter_define_desc "{" "}"
            60             ;
            61 
            62 define_desc    ->    define_desc "," "{Symbol}"
            63             |    var_type "{Symbol}"
            64             ;
            65 
            66 assign_desc    ->    assign_type "=" exp
            67             ;
            68 
            69 exp        ->    exp ">" exp1
            70         |    exp "<" exp1
            71         |    exp ">=" exp1
            72         |    exp "<=" exp1
            73         |    exp "==" exp1
            74         |    exp "and" exp1
            75         |    exp "or" exp1
            76         |    "not" exp1
            77         |    "+" exp1
            78         |    "-" exp1
            79         |    exp1
            80         ;
            81 
            82 exp1        ->    exp1 "+" exp2
            83         |    exp1 "-" exp2
            84         |    exp2
            85         ;
            86 
            87 exp2        ->    exp2 "*" exp3
            88         |    exp2 "/" exp3
            89         |    exp3
            90         ;
            91 
            92 exp3        ->    "{LQ}" exp "{RQ}"
            93         |    value_type
            94         ;

            由以上文法中僅有函數的定義和變量的定義
            有點類C的味道.
            已成功將ESLanguage大部分代碼移植到這個項目里.
            posted @ 2011-01-13 21:38 lwch 閱讀(1661) | 評論 (0)編輯 收藏
            按《自己動手寫操作系統》修改了代碼,并添加了任務0


            源碼打包下載
            posted @ 2011-01-10 18:44 lwch 閱讀(1413) | 評論 (0)編輯 收藏
            主要完成了鍵盤中斷和printf,printf_c,print_c等內核函數并刪除了一些無用的代碼
            添加了編譯環境


            源碼打包下載
            接下來研究進程調度
            posted @ 2010-12-25 16:02 lwch 閱讀(1625) | 評論 (4)編輯 收藏

            明天放出源碼..
            posted @ 2010-12-24 23:29 lwch 閱讀(465) | 評論 (0)編輯 收藏

            首先修改task1的代碼使其運行一次后進入無限循環
            將jmp _task1修改為jmp $
            將timer_interrupt修改為:

             1 _timer_interrupt:
             2     PUSH ds
             3     PUSH edx
             4     PUSH ecx
             5     PUSH ebx
             6     PUSH eax
             7     ;MOV eax,0x10
             8     ;MOV dx,ax
             9     in al,0x21            ; ┓
            10     or al,(1 << 1)    ; ┣ 屏蔽當前中斷
            11     out 0x21,al            ; ┛
            12     mov al,0x20            ; ┓置EOI位,其后8259A才能相應新的中斷
            13     out 0x20,al            ; ┛
            14     sti                            ; 允許響應新中斷
            15     in al,0x60            ; 從0x60端口讀出掃描碼
            16     ;MOV eax,1
            17     ;cmp DWORD [current],eax
            18     ;je y1
            19     ;MOV DWORD [current],eax
            20     ;JMP TSS1_SEL : 0
            21     ;jmp y2
            22 y1:
            23     ;MOV DWORD [current],0
            24     ;JMP TSS0_SEL : 0
            25     ;MOV eax,0x17
            26     ;MOV ds,ax
            27     ;MOV al,65
            28     call write_char    ; 這里僅簡單的將掃描碼作為ANSI碼打印出來
            29     ;MOV ecx,0xfff
            30 y2:
            31     cli
            32     in al,0x21                ; ┓
            33     and al,~(1 << 1)    ; ┣ 恢復接受當前中斷
            34     out 0x21,al                ; ┛
            35     POP eax
            36     POP ebx
            37     POP ecx
            38     POP edx
            39     POP ds
            40     IRET

            注:因為鍵盤中斷處理過程運行于Ring0,應此可以直接調用內核函數write_char
            然后修改IDT表的0x21(0x21對應于IRQ1,表示鍵盤中斷)項的offset_l和offset_h使其指向timer_interrupt中斷處理過程.
             1 void init_idt()
             2 {
             3     int i;
             4     for(i=0;i<256;i++)
             5     {
             6         if(0x21 == i || 0x80 == i)
             7         {
             8             continue;
             9         }
            10         setup_int_gate((dword)ignore_int,i);        
            11     }
            12     //setup_int_gate((dword)timer_interrupt,0x20);
            13     setup_int_gate((dword)timer_interrupt,0x21);
            14     setup_trap_gate((dword)system_interrupt,0x80);    
            15     
            16     idtr[0= 8 * 256;
            17     idtr[1= ((dword)&idt_[0+ KERNEL_BASE) & 0xffff;
            18     idtr[2= ((dword)&idt_[0+ KERNEL_BASE)>>16;
            19 }

            最后啟動鍵盤中斷,將8259A主片的IRQ0位設為1,IRQ1位設為0
            1     MOV edx,0x21
            2     in al,dx
            3     AND al,0xFD
            4     OUT dx,al
            注:0xFD對應二進制碼11111101
            調試結果:

            按下a鍵輸出一個字符,彈起a鍵輸出另一個字符
            由于直接將掃描碼作為ANSI碼輸出因此會出現兩個亂碼字符

            完整代碼打包下載
            posted @ 2010-12-11 17:46 lwch 閱讀(1992) | 評論 (5)編輯 收藏
            COM.h:
             1 #pragma once
             2 #include <atlcomcli.h>
             3 
             4 class COMMacro
             5 {
             6 public:
             7     COMMacro(LPTSTR Object);
             8     ~COMMacro();
             9     BOOL Invoke(LPTSTR strFunction,VARIANT* pVarParams,int nParamterCount,VARIANT* pResult);
            10     VARIANT ToVARIANT(BSTR str);
            11     VARIANT ToVARIANT(int nVal);
            12     VARIANT ToVARIANT(bool bVal);
            13     VARIANT ToVARIANT(double dVal);
            14     VARIANT ToVARIANT_ByRef(BSTR* pStr);
            15     VARIANT ToVARIANT_ByRef(int* pnVal);
            16     VARIANT ToVARIANT_ByRef(bool* pbVal);
            17     VARIANT ToVARIANT_ByRef(double* pdVal);
            18     BSTR ToBSTR(VARIANT Val);
            19     int ToInt(VARIANT Val);
            20     bool ToBool(VARIANT Val);
            21     double ToDouble(VARIANT Val);
            22 
            23     BOOL ToBSTR(LPTSTR src,BSTR& dest);
            24 protected:
            25     CLSID m_clsID;
            26     CComPtr<IUnknown> m_Unknown;
            27     CComDispatchDriver* m_pDispatchDriver;
            28 };
            COM.cpp:
              1 #include "stdafx.h"
              2 #include "COM.h"
              3 #include <comdef.h>
              4 
              5 COMMacro::COMMacro(LPTSTR Object)
              6 {
              7     HRESULT hr = CLSIDFromProgID(Object,&m_clsID);
              8     if(FAILED(hr))
              9     {
             10         throw _com_error(hr);
             11         return;
             12     }
             13     hr = CoCreateInstance(m_clsID,NULL,CLSCTX_ALL,IID_IUnknown,(LPVOID*)&m_Unknown);
             14     if(FAILED(hr))
             15     {
             16         throw _com_error(hr);
             17         return;
             18     }
             19     m_pDispatchDriver = new CComDispatchDriver(m_Unknown);
             20 }
             21 
             22 COMMacro::~COMMacro()
             23 {
             24     delete m_pDispatchDriver;
             25 }
             26 
             27 BOOL COMMacro::Invoke(LPTSTR strFunction,VARIANT* pVarParams,int nParamterCount,VARIANT* pResult)
             28 {
             29     DISPID DispID;
             30     HRESULT hr = m_pDispatchDriver->GetIDOfName(strFunction,&DispID);
             31     if(FAILED(hr))
             32     {
             33         throw _com_error(hr);
             34         return FALSE;
             35     }
             36     hr = m_pDispatchDriver->InvokeN(DispID,pVarParams,nParamterCount,pResult);
             37     if(FAILED(hr))
             38     {
             39         throw _com_error(hr);
             40         return FALSE;
             41     }
             42     return TRUE;
             43 }
             44 
             45 VARIANT COMMacro::ToVARIANT(BSTR str)
             46 {
             47     VARIANT vResult;
             48     vResult.vt = VT_BSTR;
             49     vResult.bstrVal = SysAllocString(str);
             50     return vResult;
             51 }
             52 
             53 VARIANT COMMacro::ToVARIANT(int nVal)
             54 {
             55     VARIANT vResult;
             56     vResult.vt = VT_I4;
             57     vResult.intVal = nVal;
             58     return vResult;
             59 }
             60 
             61 VARIANT COMMacro::ToVARIANT(bool bVal)
             62 {
             63     VARIANT vResult;
             64     vResult.vt = VT_BOOL;
             65     vResult.boolVal = bVal;
             66     return vResult;
             67 }
             68 
             69 VARIANT COMMacro::ToVARIANT(double dVal)
             70 {
             71     VARIANT vResult;
             72     vResult.vt = VT_R8;
             73     vResult.dblVal = dVal;
             74     return vResult;
             75 }
             76 
             77 VARIANT COMMacro::ToVARIANT_ByRef(BSTR* pStr)
             78 {
             79     VARIANT vResult;
             80     vResult.vt = VT_BSTR | VT_BYREF;
             81     vResult.byref = pStr;
             82     return vResult;
             83 }
             84 
             85 VARIANT COMMacro::ToVARIANT_ByRef(int* pnVal)
             86 {
             87     VARIANT vResult;
             88     vResult.vt = VT_I4 | VT_BYREF;
             89     vResult.byref = pnVal;
             90     return vResult;
             91 }
             92 
             93 VARIANT COMMacro::ToVARIANT_ByRef(bool* pbVal)
             94 {
             95     VARIANT vResult;
             96     vResult.vt = VT_BOOL | VT_BYREF;
             97     vResult.byref = pbVal;
             98     return vResult;
             99 }
            100 
            101 VARIANT COMMacro::ToVARIANT_ByRef(double* pdVal)
            102 {
            103     VARIANT vResult;
            104     vResult.vt = VT_BOOL | VT_BYREF;
            105     vResult.byref = pdVal;
            106     return vResult;
            107 }
            108 
            109 BSTR COMMacro::ToBSTR(VARIANT Val)
            110 {
            111     return *(BSTR*)Val.byref;
            112 }
            113 
            114 int COMMacro::ToInt(VARIANT Val)
            115 {
            116     return *(int*)Val.byref;
            117 }
            118 
            119 bool COMMacro::ToBool(VARIANT Val)
            120 {
            121     return *(bool*)Val.byref;
            122 }
            123 
            124 double COMMacro::ToDouble(VARIANT Val)
            125 {
            126     return *(double*)Val.byref;
            127 }
            128 
            129 BOOL COMMacro::ToBSTR(LPTSTR src,BSTR& dest)
            130 {
            131     dest = SysAllocString(src);
            132     return TRUE;
            133 }

            使用說明:
            1.構造函數:
            參數(字符串常量):工程名.類名
            2.Invoke:
            參數1(字符串常量):函數名
            參數2(VARIANT數組):調用參數,從右至左
            參數3(數值常量):調用參數個數
            參數4(VARIANT指針):返回值
            3.ToVARIANT:將給定參數轉換為VARIANT類型
            4.ToVARIANT_ByRef:將給定參數轉換為ByRef的VARIANT類型
            5.ToBSTR:將給定ByRef的VARIANT轉換為BSTR
            6.ToInt:將給定ByRef的VARIANT轉換為int
            7.ToBool:將給定ByRef的VARIANT轉換為bool
            8.ToDouble:將給定ByRef的VARIANT轉換為double
            9.ToBSTR:將給定字符串常量轉換為BSTR類型

            示例:
             1     CoInitialize(0); // 初始化ATL
             2     try
             3     {
             4         COMMacro m(L"aaa.bbb");
             5         VARIANT vResult,vParams[3];
             6         int i = 100;
             7         BSTR str;
             8         m.ToBSTR(L"abc",str);
             9         vParams[2= m.ToVARIANT(123.456);
            10         vParams[1= m.ToVARIANT(i);
            11         vParams[0= m.ToVARIANT_ByRef(&str);
            12         m.Invoke(L"aaa",vParams,3,&vResult);
            13         wprintf(L"%s\n",m.ToBSTR(vParams[0]));
            14     }
            15     catch(_com_error& e)
            16     {
            17         wprintf(L"%s\n",e.ErrorMessage());
            18     }
            posted @ 2010-11-20 22:40 lwch 閱讀(786) | 評論 (0)編輯 收藏
            代碼:
             1 function fact(integer n) as integer
             2     if n > 1 then
             3         return fact(n - 1* n
             4     else
             5         return n
             6     end if
             7 end function
             8 
             9 function main()
            10     integer Result
            11     Result = fact(5)
            12 end function
            符號表:
             0    n
             
            1    1
             
            2    fact
             
            3    Result
             
            4    5
             
            5    main
            翻譯結果:
             
            posted @ 2010-10-02 11:56 lwch 閱讀(1152) | 評論 (0)編輯 收藏
            僅列出標題
            共7頁: 1 2 3 4 5 6 7 
            亚洲午夜久久久影院| 久久综合色老色| 亚洲综合日韩久久成人AV| 狠狠久久综合| 久久免费国产精品一区二区| 久久永久免费人妻精品下载| 狠狠色丁香久久婷婷综合_中| 久久亚洲精品无码观看不卡| 99国内精品久久久久久久| 久久精品免费一区二区三区| 国产亚洲欧美精品久久久| 久久发布国产伦子伦精品| 午夜精品久久久久久久久| 久久综合给合久久狠狠狠97色| 久久亚洲AV成人无码| 97精品国产97久久久久久免费| 久久久久久久久波多野高潮| 久久人妻AV中文字幕| 久久精品国产亚洲AV香蕉| A级毛片无码久久精品免费| 老色鬼久久亚洲AV综合| 国产精品久久久久jk制服| 久久青青草原综合伊人| 国产精品伊人久久伊人电影| 久久精品中文字幕第23页| 婷婷久久综合九色综合绿巨人| 国产精品99久久久精品无码| 久久婷婷五月综合97色| 久久综合久久综合九色| 久久精品国产99久久丝袜| 国内精品久久久久影院薰衣草| 久久国产高潮流白浆免费观看| 国产精品美女久久久久av爽| 欧美午夜精品久久久久久浪潮| 久久久久亚洲av成人网人人软件| 国产成人精品免费久久久久| 九九久久精品国产| 囯产精品久久久久久久久蜜桃| 久久久久国产一级毛片高清版| 久久久午夜精品| 色综合久久综合网观看|