乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      vs2019 Com組件初探-實(shí)現(xiàn)vbs的CreateObject函數(shù)邏輯

       頭號碼甲 2021-06-27

      vs2019 Com組件初探-簡單的COM編寫以及實(shí)現(xiàn)跨語言調(diào)用

      上一篇實(shí)現(xiàn)了如何編寫基于IDispatch接口的COM以及vbs如何調(diào)用編寫的COM

      本次主要是實(shí)現(xiàn)VBS的CreateObject函數(shù)的邏輯,也就是在不知道類名的情況下如何調(diào)用基于IDispathc接口的COM

      前提條件

        1、掌握C++基礎(chǔ)語法

        2、平臺安裝 vs2019

        3、本地平臺為 windows 10 1909 X64

        4、基本的DLL編程知識 (不是必備)

      本次目標(biāo)

        1、創(chuàng)建DLL并實(shí)現(xiàn)CreateObject函數(shù)

        2、寫一個調(diào)用DLL的demo

      1、創(chuàng)建DLL并實(shí)現(xiàn)CreateObject函數(shù)

        首先通過VS創(chuàng)建一個 動態(tài)鏈接庫

        

        在編寫之前先梳理程序的執(zhí)行流程

          初始化 Com庫

          獲取函數(shù)指針

          傳入?yún)?shù) 

          調(diào)用函數(shù)指針

          卸載Com庫

        接下來就開始寫我們的DLL

          vs2019 創(chuàng)建DLL項(xiàng)目后系統(tǒng)會默認(rèn)多出來頭文件

            

          以及源文件

            

        我們打開pch.h頭文件定義我們的函數(shù)聲明

          

          參數(shù)為 COM組件progID,函數(shù)名,參數(shù)數(shù)量,變長參數(shù)

          extern "C" 以C的方式定義

          _declspec(dllimport) 定義此函數(shù)為要導(dǎo)出的函數(shù)

        新建一個ComInit.h 定義Com庫的初始化和卸載庫函數(shù)

       1 // ComInit.h 2  3 #pragma once 4 static bool _init = false; 5  6 // 初始化 7 bool Init(); 8  9 // 結(jié)束初始化10 void Release();

        新建一個ComInit.cpp 實(shí)現(xiàn)Init和Release函數(shù)

      // ComInit.cpp#include "pch.h"#include "ComInit.h"bool Init()
      {if (_init == true)
          {return _init;
          }else{if (S_OK == CoInitialize(NULL))
                  _init = true;else_init = false;return _init;
          }return false;
      }void Release()
      {if (true == _init)
          {
              CoUninitialize();
              _init = false;
          }
      }

        之后打開pch.cpp實(shí)現(xiàn)CreateObject函數(shù)

       1 #include "pch.h" 2 #include "ComStart.h" 3 #include <assert.h> 4 #include <atlbase.h> 5  6 // 報錯宏 7 #define ASSERT(s) if((s) == true) 8  9 // Com類名,函數(shù)名,傳入的參數(shù)數(shù)量,變長參數(shù)10 VARIANT CreateObject(const WCHAR* __comname,const WCHAR* __funcname,int __count, ...)11 {12     /* Com注冊到系統(tǒng)后使用 */13    14     // 是否成功初始化15     if (true == Init())16     {17         // ProgId值存放18         CLSID clsid;19 20         // 通過 ProgID 取得組件的 CLSID21         // CLSID 值存放在注冊表 HKEY_CLASSES_ROOT [以__comname加.1為鍵值(MyCom.FirstClass.1)]22         HRESULT hr = ::CLSIDFromProgID(__comname, &clsid);23 24         ASSERT(S_OK != hr)25             assert(hr != S_OK);26 27         // 智能指針獲取 IUnknow28         CComPtr<IUnknown>spUnk;29 30         /* 31         *   CoCreateInstance32         *       CLSIDFromProgId獲取的值33         *       指向接口IUnknown的指針34         *       運(yùn)行可執(zhí)行代碼的上下文[CLSCTX_ALL 為所有]35         *       IID_IUnknown為返回類型36         *       用來接收指向Com對象接口地址的指針變量37         */38         // 獲取IUnknow內(nèi)容 39         hr = ::CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_IUnknown, (LPVOID*)&spUnk);40 41         ASSERT(S_OK != hr)42             assert(hr != S_OK);43         44         // 通過IUnknown智能指針,聲明新的IDispatch智能指針45         CComDispatchDriver spDisp(spUnk);46 47         // 參數(shù)數(shù)組48         VARIANT* __args = new VARIANT[__count];49 50         // 變長參數(shù)變量51         va_list ap;52 53         // 定位到第一個函數(shù)變長參數(shù)54         va_start(ap, __count);55 56         // 循環(huán)獲取變長參數(shù),并轉(zhuǎn)換為 VARIANT 類型放入 __args變量57         for (auto i = 0; i < __count; i++)58             __args[i] = va_arg(ap, VARIANT);59 60         // 結(jié)束變長參數(shù)61         va_end(ap);62 63         // Com函數(shù)返回值存放64         VARIANT __ret;65 66         // 執(zhí)行Com函數(shù)67 68         /*69         *   [InvokeN]70         *       函數(shù)名71         *       函數(shù)參數(shù)72         *       函數(shù)數(shù)量73         *       返回值存放處74         */75         hr = spDisp.InvokeN((LPCOLESTR)__funcname, __args, __count, &__ret);76        77         ASSERT(S_OK != hr)78             assert(hr != S_OK);79 80         // 內(nèi)存回收81         delete[] __args;82 83         // 卸載 Com庫84         Release();85 86         // 返回值87         return __ret;88     }89 90     assert(_init == false);91 }

        完成后編譯(CTRL+B)獲取到新的dll和lib文件(x64)以及項(xiàng)目的pch.h頭文件

          

          

      2、寫一個調(diào)用DLL的demo

        vs2019 新建基于 控制臺程序 的項(xiàng)目

        

        移動dll和lib以及pch.h文件到新建項(xiàng)目目錄下,并對pch.h文件添加代碼

      // pch.h#pragma once#include <combaseapi.h>// 新添加的代碼#pragma comment(lib,"ComPack.lib")extern "C" _declspec(dllimport) VARIANT CreateObject(const WCHAR * __comname, const WCHAR * __funcname, int __count, ...);

         找到main函數(shù) 寫入調(diào)用代碼

      #include <iostream>#include "pch.h"int main()
      {// 參數(shù)類型必須為VARIANT    VARIANT __param1;// 參數(shù)類型為 LONG__param1.vt = VT_I4;// 參數(shù)值為 2__param1.lVal = 2;// 獲取ComTest.Temp并調(diào)用Number 函數(shù) 參數(shù)數(shù)量為1 對Number函數(shù)傳入?yún)?shù)__param1VARIANT __ret = CreateObject(L"ComTest.Temp", L"Number",1, __param1);
      
          std::cout << __ret.lVal << std::endl;
      }

        執(zhí)行并運(yùn)行顯示執(zhí)行結(jié)果

        

        運(yùn)行出現(xiàn)錯誤,檢查調(diào)用的Com是否已經(jīng)注冊

        如何注冊我在上一篇里面有講過

        接下來修改代碼嘗試調(diào)用Wscript.shell里面的Run函數(shù)

      #include <iostream>#include "pch.h"int main()
      {
          VARIANT __param1;// 參數(shù)類型為BSTR__param1.vt = VT_BSTR;// 創(chuàng)建BSTR格式的字符串__param1.bstrVal = SysAllocString(L"notepad.exe");// 調(diào)用函數(shù)并釋放BSTRVARIANT __ret = CreateObject(L"Wscript.shell", L"run",1, __param1);
          SysFreeString(__param1.bstrVal);
      }

        值得一提的是 COM組件的字符串和以往的字符串有所不同,創(chuàng)建方式和銷毀方式也不同

        SysAllocString為創(chuàng)建BSTR字符串

        SysFreeString 為釋放BSTR字符串

        運(yùn)行結(jié)果可以看到已經(jīng)成功的執(zhí)行了系統(tǒng)命令,打開了一個記事本

        

      注意事項(xiàng):

        com基于IDispatch 接口才可以調(diào)用

        Com必須已經(jīng)注冊到系統(tǒng) (小心誤刪或者移動路徑)

        卸載DLL函數(shù)為  regsvr32.exe -ui [DLL未知]

        DLL對應(yīng)版本盡量一致

      github源碼:

        3065190005/ComTest: ComTest Code (github.com)

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多