簡體   English   中英

如何在C ++命令行界面程序中運行COM(.ocx)對象。 (VS2017)

[英]How do I run a COM (.ocx) object in a C++ command line interface program. (VS2017)

如何在C ++命令行界面程序中運行COM(.ocx)對象。 (VS2017)

經過數小時的研究,我得出以下結論。 我認為隨着三重奏的填充,COM對象正在加載。 但是我不知道如何成功運行它。 它可能需要附加到CWND或其他東西。

我有此代碼,可能是錯誤的兔子洞。 它崩潰得很厲害。

  HRESULT hr;
   hr = CoInitialize(0);
   assert(SUCCEEDED(hr));
   {
      static CLSID const clsid
         = { 0xf1933967, 0x74b0, 0x11d3,{ 0x8a, 0x13, 0x0, 0x40, 0x33, 0x93, 0xb2, 0x36 } };
      //CLSID ClassID;
      //hr = CLSIDFromProgID(OLESTR("TrioPCLib.TrioPC"), &ClassID);
      assert(SUCCEEDED(hr)); 
      TrioPCLib::_DTrioPCPtr trio;
      IID iid = TrioPCLib::_DTrioPCPtr::GetIID();
      hr = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, iid, reinterpret_cast<void**>(&trio));
      assert(SUCCEEDED(hr));
      trio->Release();

   }
   CoUninitialize();

COM對象具有GUI,我不需要使用它。 我只想調用API。

更新:ActiveX已加載,我可以調用例如AboutBox()並顯示它。 它在CoUninitialize()上崩潰,但有異常...

TestVpu.exe中0x779CA899(ntdll.dll)的未處理異常:0xC0000374:堆已損壞(參數:0x77A05910)。

我願意打賭,異常實際上是在CoUninitialize發生的,而不是CoUninitialize調用。 看起來您可能要兩次釋放COM對象,一次顯式釋放一次,然后一次隱式釋放一次。

您正在顯式調用trio->Release() 您還使用了TrioPCLib::_DTrioPCPtr ,它可能是Visual C ++編譯器在遇到#import生成的COM智能指針。 超出范圍時,此類會自動在被引用的對象上調用Release

您應該使用TrioPCLib::_DTrioPC*也不應調用trio->Release() (FWIW:我更喜歡使用TrioPCLib::_DTrioPCPtr而不是顯式調用trio->Release() 。)

以下內容似乎更加穩定。 它使用指針並調用Release。 導入還有一些額外的參數。 導入生成您可以查看的代碼。 該類派生自IDispatch,並使用_com_dispatch_method()進行調用。 到目前為止,我不需要擔心消息泵。

#include "stdafx.h"
#include <iostream>
using namespace std;
#import "C:/Users/*****/Documents/Trio Motion Solutions/TrioMCTools/Debug/Win32/TrioPC.ocx" named_guids no_namespace

int main(int, char**)
{
    CoInitialize(0);
    {
        bool inOK = false;
        int length = 3;

        _DTrioPC* pitd = 0;
        HRESULT hr = CoCreateInstance(CLSID_TrioPC, 0, CLSCTX_ALL, DIID__DTrioPC, reinterpret_cast<void**>(&pitd));
        if (SUCCEEDED(hr)) cout << "ok" << endl; else cout << "nok" << endl;

        pitd->SetHost("192.168.0.250");
        bool openOK = pitd->Open(2, 0);
        if (openOK) cout << "ok" << endl; else cout << "nok" << endl;


        SAFEARRAY *data = SafeArrayCreateVectorEx(VT_R8, 0, length, NULL);

        if (data)
        {
            double *safe_data;
            hr = SafeArrayAccessData(data, (void **)&safe_data);
            if (SUCCEEDED(hr))
            {
                int i;
                for (i = 0; i < length; i++)
                    safe_data[i] = i+532;
                SafeArrayUnaccessData(data);

                VARIANT arg;
                VariantInit(&arg);
                arg.vt = VT_ARRAY | VT_R8;
                arg.parray = data;

                inOK = pitd->SetTable(1000, 3, &arg);
            }
        }
        pitd->Release();
    }
    CoUninitialize();

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM