[英]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.