| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903 |
- #include "ActiveXWrapper.h"
- #include "Logger.h"
- #include <sstream>
- #include <iomanip>
- #include <algorithm>
- #include <comutil.h> // 添加这个包含以使用_com_util::ConvertBSTRToString
- // ActiveXEventSink 实现
- ActiveXEventSink::ActiveXEventSink(CommEventCallback callback)
- : ref_count_(1), callback_(callback)
- {
- }
- ActiveXEventSink::~ActiveXEventSink()
- {
- }
- // 修复QueryInterface函数 - 支持ICommModifyKitEvents接口
- STDMETHODIMP ActiveXEventSink::QueryInterface(REFIID riid, void **ppvObject)
- {
- if (!ppvObject)
- {
- return E_POINTER;
- }
- *ppvObject = nullptr;
- if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IDispatch))
- {
- *ppvObject = static_cast<IDispatch *>(this);
- AddRef();
- return S_OK;
- }
- // 支持事件接口
- if (IsEqualIID(riid, IID_ICommModifyKitEvents))
- {
- *ppvObject = static_cast<IDispatch *>(this);
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG)
- ActiveXEventSink::AddRef()
- {
- return InterlockedIncrement(&ref_count_);
- }
- STDMETHODIMP_(ULONG)
- ActiveXEventSink::Release()
- {
- ULONG count = InterlockedDecrement(&ref_count_);
- if (count == 0)
- {
- delete this;
- }
- return count;
- }
- STDMETHODIMP ActiveXEventSink::GetTypeInfoCount(UINT *pctinfo)
- {
- *pctinfo = 0;
- return S_OK;
- }
- STDMETHODIMP ActiveXEventSink::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP ActiveXEventSink::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP ActiveXEventSink::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
- DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
- {
- // 清空并重写函数,只处理6个参数的情况
- // 6个参数从DISPPARAMS *pDispParams中解析出来
- // 检查参数是否有效
- if (!pDispParams)
- {
- LOG_ERROR("Invalid DISPPARAMS");
- return E_INVALIDARG;
- }
- // 检查参数数量是否为6
- if (pDispParams->cArgs != 6)
- {
- LOG_ERROR("Expected 6 parameters, but got " + std::to_string(pDispParams->cArgs));
- return E_INVALIDARG;
- }
- try
- {
- // 从pDispParams中解析6个参数
- VARIANT *args = pDispParams->rgvarg;
- // 解析参数(注意:VARIANT参数是逆序的)
- // 参数6: lpData (char*)
- char *lpData = nullptr;
- if (args[0].vt == VT_BYREF || args[0].vt == (VT_ARRAY | VT_UI1))
- {
- // 处理数组数据
- if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
- {
- SAFEARRAY *data = args[0].parray;
- BYTE *data_ptr;
- SafeArrayAccessData(data, reinterpret_cast<void **>(&data_ptr));
- lpData = reinterpret_cast<char *>(data_ptr);
- }
- }
- else if (args[0].vt == VT_BSTR)
- {
- // 处理字符串数据
- lpData = _com_util::ConvertBSTRToString(args[0].bstrVal);
- }
- // 参数5: dwSize (DWORD)
- DWORD dwSize = 0;
- if (args[1].vt == VT_I4 || args[1].vt == VT_UI4)
- {
- dwSize = static_cast<DWORD>(args[1].lVal);
- }
- // 参数4: Irp (DWORD)
- DWORD Irp = 0;
- if (args[2].vt == VT_I4 || args[2].vt == VT_UI4)
- {
- Irp = static_cast<DWORD>(args[2].lVal);
- }
- // 参数3: ComNumber (DWORD)
- DWORD ComNumber = 0;
- if (args[3].vt == VT_I4 || args[3].vt == VT_UI4)
- {
- ComNumber = static_cast<DWORD>(args[3].lVal);
- }
- // 参数2: dTime (TDateTime/double)
- // TDateTime dTime = 0.0;
- // if (args[4].vt == VT_R8)
- //{
- // dTime = static_cast<TDateTime>(args[4].dblVal);
- //}
- // 参数1: Sequence (int)
- int Sequence = 0;
- if (args[5].vt == VT_I4)
- {
- Sequence = args[5].lVal;
- }
- // 打印6个参数值的日志
- LOG_DEBUG("ActiveX event parameters:");
- // LOG_DEBUG(" Sequence: " + std::to_string(Sequence));
- // LOG_DEBUG(" dTime: " + std::to_string(dTime));
- LOG_DEBUG(" ComNumber: " + std::to_string(ComNumber));
- LOG_DEBUG(" Irp: " + std::to_string(Irp));
- LOG_DEBUG(" dwSize: " + std::to_string(dwSize));
- LOG_DEBUG(" lpData: " + std::to_string(reinterpret_cast<uintptr_t>(lpData)));
- // 调用回调函数
- if (callback_)
- {
- try
- {
- // 创建CommEventData结构以传递给回调函数
- CommEventData event_data;
- event_data.event_type = static_cast<CommEventType>(Irp);
- event_data.port = static_cast<int>(ComNumber);
- if (lpData && dwSize > 0)
- {
- event_data.data.assign(reinterpret_cast<BYTE *>(lpData), reinterpret_cast<BYTE *>(lpData) + dwSize);
- }
- event_data.data_size = dwSize;
- callback_(event_data);
- LOG_DEBUG("ActiveX event processed successfully");
- }
- catch (const std::exception &e)
- {
- LOG_ERROR("Error in ActiveX event callback: " + std::string(e.what()));
- // 释放分配的内存
- if (args[0].vt == VT_BSTR && lpData)
- {
- delete[] lpData;
- }
- else if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
- {
- SafeArrayUnaccessData(args[0].parray);
- }
- return E_FAIL;
- }
- }
- // 释放分配的内存
- if (args[0].vt == VT_BSTR && lpData)
- {
- delete[] lpData;
- }
- else if (args[0].vt == (VT_ARRAY | VT_UI1) && args[0].parray)
- {
- SafeArrayUnaccessData(args[0].parray);
- }
- }
- catch (const std::exception &e)
- {
- LOG_ERROR("Error processing ActiveX event: " + std::string(e.what()));
- return E_FAIL;
- }
- return S_OK;
- }
- // ActiveXWrapper 实现
- ActiveXWrapper::ActiveXWrapper()
- : activex_control_(nullptr), connection_point_(nullptr), connection_cookie_(0),
- event_sink_(nullptr), event_connected_(false)
- {
- }
- ActiveXWrapper::~ActiveXWrapper()
- {
- Cleanup();
- }
- bool ActiveXWrapper::Initialize()
- {
- if (initialized_)
- {
- return true;
- }
- // 初始化COM
- HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if (FAILED(hr) && hr != S_FALSE)
- {
- LOG_ERROR("Failed to initialize COM, HRESULT: " + std::to_string(hr));
- return false;
- }
- // 使用正确的CLSID创建ActiveX控件
- hr = CoCreateInstance(CLSID_CommModifyKit, nullptr, CLSCTX_INPROC_SERVER,
- IID_IDispatch, reinterpret_cast<void **>(&activex_control_));
- if (FAILED(hr))
- {
- LOG_ERROR("Failed to create ActiveX control, HRESULT: " + std::to_string(hr));
- // 尝试使用ProgID创建
- CLSID clsid;
- hr = CLSIDFromProgID(L"PCommMKit.CommModifyKit", &clsid);
- if (SUCCEEDED(hr))
- {
- hr = CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER,
- IID_IDispatch, reinterpret_cast<void **>(&activex_control_));
- }
- if (FAILED(hr))
- {
- LOG_ERROR("Failed to create ActiveX control using ProgID, HRESULT: " + std::to_string(hr));
- return false;
- }
- }
- if (!InitializeMethodIds())
- {
- LOG_ERROR("Failed to initialize method IDs");
- return false;
- }
- // 连接事件
- if (!ConnectEvents())
- {
- LOG_ERROR("Failed to connect events");
- return false;
- }
- initialized_ = true;
- LOG_INFO("ActiveX control initialized successfully");
- return true;
- }
- bool ActiveXWrapper::ConnectEvents()
- {
- if (!activex_control_)
- {
- return false;
- }
- // 获取连接点容器
- IConnectionPointContainer *cpc = nullptr;
- HRESULT hr = activex_control_->QueryInterface(IID_IConnectionPointContainer,
- reinterpret_cast<void **>(&cpc));
- if (FAILED(hr))
- {
- LOG_ERROR("Failed to get connection point container, HRESULT: " + std::to_string(hr));
- return false;
- }
- // 首先尝试直接查找事件接口的连接点
- hr = cpc->FindConnectionPoint(IID_ICommModifyKitEvents, &connection_point_);
- if (SUCCEEDED(hr))
- {
- LOG_INFO("Found connection point for ICommModifyKitEvents directly");
- }
- else
- {
- LOG_WARNING("Direct connection point lookup failed, HRESULT: " + std::to_string(hr) + ", trying enumeration");
- // 如果直接查找失败,枚举所有连接点
- IEnumConnectionPoints *enum_cp = nullptr;
- hr = cpc->EnumConnectionPoints(&enum_cp);
- if (SUCCEEDED(hr))
- {
- IConnectionPoint *cp = nullptr;
- ULONG fetched = 0;
- // 枚举所有连接点,查找正确的事件接口
- while (enum_cp->Next(1, &cp, &fetched) == S_OK && fetched > 0)
- {
- IID iid;
- if (SUCCEEDED(cp->GetConnectionInterface(&iid)))
- {
- // 记录找到的接口ID用于调试
- char iid_str[64];
- sprintf_s(iid_str, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
- iid.Data1, iid.Data2, iid.Data3,
- iid.Data4[0], iid.Data4[1], iid.Data4[2], iid.Data4[3],
- iid.Data4[4], iid.Data4[5], iid.Data4[6], iid.Data4[7]);
- LOG_DEBUG("Found connection point with IID: " + std::string(iid_str));
- // 检查是否是我们需要的事件接口
- if (IsEqualIID(iid, IID_ICommModifyKitEvents))
- {
- connection_point_ = cp;
- connection_point_->AddRef();
- cp->Release(); // 释放枚举得到的引用
- LOG_INFO("Found ICommModifyKitEvents connection point through enumeration");
- break;
- }
- }
- cp->Release();
- }
- enum_cp->Release();
- }
- }
- cpc->Release();
- if (!connection_point_)
- {
- LOG_ERROR("Failed to find any connection point for ICommModifyKitEvents");
- return false;
- }
- // 创建事件接收器
- event_sink_ = new ActiveXEventSink([this](const CommEventData &event_data)
- {
- // 直接使用通用事件数据调用通用回调
- if (event_callback_) {
- event_callback_(event_data);
- } });
- // 连接事件接收器
- hr = connection_point_->Advise(event_sink_, &connection_cookie_);
- if (FAILED(hr))
- {
- LOG_ERROR("Failed to advise connection point, HRESULT: " + std::to_string(hr));
- event_sink_->Release();
- event_sink_ = nullptr;
- return false;
- }
- event_connected_ = true;
- LOG_INFO("ActiveX events connected successfully, cookie: " + std::to_string(connection_cookie_));
- return true;
- }
- void ActiveXWrapper::DisconnectEvents()
- {
- if (event_connected_ && connection_point_ && connection_cookie_ != 0)
- {
- connection_point_->Unadvise(connection_cookie_);
- connection_cookie_ = 0;
- event_connected_ = false;
- }
- if (connection_point_)
- {
- connection_point_->Release();
- connection_point_ = nullptr;
- }
- if (event_sink_)
- {
- event_sink_->Release();
- event_sink_ = nullptr;
- }
- }
- bool ActiveXWrapper::InitializeMethodIds()
- {
- if (!activex_control_)
- {
- return false;
- }
- // 获取方法的DISPID
- LPOLESTR method_names[] = {
- const_cast<LPOLESTR>(L"InitMonitor"),
- const_cast<LPOLESTR>(L"MonitorPort"),
- const_cast<LPOLESTR>(L"StopPort"),
- const_cast<LPOLESTR>(L"ReadData"),
- const_cast<LPOLESTR>(L"WriteData"),
- const_cast<LPOLESTR>(L"FreeMonitor"),
- const_cast<LPOLESTR>(L"GetLastError")};
- DISPID *method_ids[] = {
- &init_monitor_id_,
- &monitor_port_id_,
- &stop_port_id_,
- &read_data_id_,
- &write_data_id_,
- &free_monitor_id_,
- &get_last_error_id_};
- for (int i = 0; i < 7; i++)
- {
- HRESULT hr = activex_control_->GetIDsOfNames(IID_NULL, &method_names[i], 1,
- LOCALE_USER_DEFAULT, method_ids[i]);
- if (FAILED(hr))
- {
- LOG_ERROR("Failed to get method ID for method");
- return false;
- }
- }
- return true;
- }
- HRESULT ActiveXWrapper::InvokeMethod(DISPID dispid, VARIANT *params, int param_count, VARIANT *result)
- {
- if (!activex_control_)
- {
- return E_FAIL;
- }
- DISPPARAMS disp_params = {params, nullptr, param_count, 0};
- EXCEPINFO excep_info = {0};
- UINT arg_err = 0;
- return activex_control_->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
- DISPATCH_METHOD, &disp_params, result,
- &excep_info, &arg_err);
- }
- bool ActiveXWrapper::InitMonitor(const std::string &key)
- {
- if (!initialized_)
- {
- LOG_ERROR("ActiveX control not initialized");
- return false;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- if (callback_initialized_)
- {
- return true;
- }
- // 转换字符串参数
- _bstr_t bstr_key(key.c_str());
- VARIANT param;
- VariantInit(¶m);
- param.vt = VT_BSTR;
- param.bstrVal = bstr_key;
- VARIANT result;
- VariantInit(&result);
- HRESULT hr = InvokeMethod(init_monitor_id_, ¶m, 1, &result);
- bool success = false;
- if (SUCCEEDED(hr) && result.vt == VT_BOOL)
- {
- success = result.boolVal != VARIANT_FALSE;
- callback_initialized_ = success;
- }
- VariantClear(¶m);
- VariantClear(&result);
- if (success)
- {
- LOG_INFO("InitMonitor succeeded");
- }
- else
- {
- LOG_ERROR("InitMonitor failed, error code: " + std::to_string(GetLastError()));
- }
- return success;
- }
- bool ActiveXWrapper::MonitorPort(int port)
- {
- if (!initialized_ || !callback_initialized_)
- {
- LOG_ERROR("ActiveX control not properly initialized");
- return false;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- VARIANT param;
- VariantInit(¶m);
- param.vt = VT_I4;
- param.lVal = port;
- VARIANT result;
- VariantInit(&result);
- HRESULT hr = InvokeMethod(monitor_port_id_, ¶m, 1, &result);
- bool success = false;
- if (SUCCEEDED(hr) && result.vt == VT_BOOL)
- {
- success = result.boolVal != VARIANT_FALSE;
- if (success)
- {
- monitored_ports_[port] = true;
- }
- }
- VariantClear(¶m);
- VariantClear(&result);
- if (success)
- {
- LOG_INFO("MonitorPort succeeded for port " + std::to_string(port));
- }
- else
- {
- LOG_ERROR("MonitorPort failed for port " + std::to_string(port) + ", error code: " + std::to_string(GetLastError()));
- }
- return success;
- }
- bool ActiveXWrapper::StopPort(int port)
- {
- if (!initialized_)
- {
- LOG_ERROR("ActiveX control not initialized");
- return false;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- VARIANT param;
- VariantInit(¶m);
- param.vt = VT_I4;
- param.lVal = port;
- VARIANT result;
- VariantInit(&result);
- HRESULT hr = InvokeMethod(stop_port_id_, ¶m, 1, &result);
- bool success = false;
- if (SUCCEEDED(hr) && result.vt == VT_BOOL)
- {
- success = result.boolVal != VARIANT_FALSE;
- if (success)
- {
- monitored_ports_[port] = false;
- }
- }
- VariantClear(¶m);
- VariantClear(&result);
- if (success)
- {
- LOG_INFO("StopPort succeeded for port " + std::to_string(port));
- }
- else
- {
- LOG_ERROR("StopPort failed for port " + std::to_string(port) + ", error code: " + std::to_string(GetLastError()));
- }
- return success;
- }
- // 修复ReadData函数 - 移除SafeArrayDestroy双重释放
- bool ActiveXWrapper::ReadData(int port, const std::string &hex_data)
- {
- if (!initialized_)
- {
- LOG_ERROR("ActiveX control not initialized");
- return false;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- // 将十六进制字符串转换为字节数组
- std::vector<BYTE> bytes = Utils::ConvertHexStringToBytes(hex_data);
- // 使用辅助函数创建SafeArray
- SAFEARRAY *sa = CreateSafeArrayFromBytes(bytes);
- if (!sa)
- {
- LOG_ERROR("Failed to create SafeArray");
- return false;
- }
- // 准备参数
- VARIANT params[3];
- VariantInit(¶ms[0]);
- VariantInit(¶ms[1]);
- VariantInit(¶ms[2]);
- params[0].vt = VT_I4;
- params[0].lVal = port;
- params[1].vt = VT_ARRAY | VT_UI1;
- params[1].parray = sa;
- params[2].vt = VT_I4;
- params[2].lVal = static_cast<LONG>(bytes.size());
- VARIANT result;
- VariantInit(&result);
- // 调用ActiveX控件的ReadData方法
- HRESULT hr = InvokeMethod(read_data_id_, params, 3, &result);
- bool success = SUCCEEDED(hr);
- if (success && result.vt == VT_BOOL)
- {
- success = result.boolVal != VARIANT_FALSE;
- }
- // 只清理VARIANT,VariantClear会自动处理SafeArray
- for (int i = 0; i < 3; i++)
- {
- VariantClear(¶ms[i]);
- }
- VariantClear(&result);
- // 不要调用SafeArrayDestroy(sa) - 这会导致双重释放崩溃
- if (success)
- {
- LOG_DEBUG("ReadData succeeded for port " + std::to_string(port) + ", data: " + hex_data);
- }
- else
- {
- LOG_ERROR("ReadData failed for port " + std::to_string(port) + ", HRESULT: " + std::to_string(hr));
- }
- return success;
- }
- // 修复WriteData函数 - 移除SafeArrayDestroy双重释放
- bool ActiveXWrapper::WriteData(int port, const std::string &hex_data)
- {
- if (!initialized_)
- {
- LOG_ERROR("ActiveX control not initialized");
- return false;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- // 将十六进制字符串转换为字节数组
- std::vector<BYTE> bytes = Utils::ConvertHexStringToBytes(hex_data);
- // 使用辅助函数创建SafeArray
- SAFEARRAY *sa = CreateSafeArrayFromBytes(bytes);
- if (!sa)
- {
- LOG_ERROR("Failed to create SafeArray");
- return false;
- }
- // 准备参数
- VARIANT params[3];
- VariantInit(¶ms[0]);
- VariantInit(¶ms[1]);
- VariantInit(¶ms[2]);
- params[0].vt = VT_I4;
- params[0].lVal = port;
- params[1].vt = VT_ARRAY | VT_UI1;
- params[1].parray = sa;
- params[2].vt = VT_I4;
- params[2].lVal = static_cast<LONG>(bytes.size());
- VARIANT result;
- VariantInit(&result);
- // 调用ActiveX控件的WriteData方法
- HRESULT hr = InvokeMethod(write_data_id_, params, 3, &result);
- bool success = SUCCEEDED(hr);
- if (success && result.vt == VT_BOOL)
- {
- success = result.boolVal != VARIANT_FALSE;
- }
- // 只清理VARIANT,VariantClear会自动处理SafeArray
- for (int i = 0; i < 3; i++)
- {
- VariantClear(¶ms[i]);
- }
- VariantClear(&result);
- // 不要调用SafeArrayDestroy(sa) - 这会导致双重释放崩溃
- if (success)
- {
- LOG_DEBUG("WriteData succeeded for port " + std::to_string(port) + ", data: " + hex_data);
- }
- else
- {
- LOG_ERROR("WriteData failed for port " + std::to_string(port) + ", HRESULT: " + std::to_string(hr));
- }
- return success;
- }
- bool ActiveXWrapper::FreeMonitor()
- {
- if (!initialized_)
- {
- return true;
- }
- std::lock_guard<std::mutex> lock(mutex_);
- VARIANT result;
- VariantInit(&result);
- HRESULT hr = InvokeMethod(free_monitor_id_, nullptr, 0, &result);
- bool success = SUCCEEDED(hr);
- if (success)
- {
- callback_initialized_ = false;
- monitored_ports_.clear();
- LOG_INFO("FreeMonitor succeeded");
- }
- else
- {
- LOG_ERROR("FreeMonitor failed");
- }
- VariantClear(&result);
- return success;
- }
- int ActiveXWrapper::GetLastError()
- {
- if (!initialized_)
- {
- return -1;
- }
- VARIANT result;
- VariantInit(&result);
- HRESULT hr = InvokeMethod(get_last_error_id_, nullptr, 0, &result);
- int error_code = -1;
- if (SUCCEEDED(hr) && result.vt == VT_I4)
- {
- error_code = result.lVal;
- }
- VariantClear(&result);
- return error_code;
- }
- void ActiveXWrapper::SetEventCallback(CommEventCallback callback)
- {
- // 调用基类的实现来设置回调
- CommWrapperBase::SetEventCallback(callback);
- // 设置ActiveX事件回调,将ActiveX事件数据转换为通用事件数据后再调用通用回调
- event_callback_ = [this](const CommEventData &event_data)
- {
- // 调用通用回调
- if (event_callback_)
- {
- event_callback_(event_data);
- }
- };
- }
- std::string ActiveXWrapper::GetErrorMessage(int error_code)
- {
- switch (error_code)
- {
- case -241:
- return "安装驱动失败";
- case -243:
- return "其他错误";
- case -244:
- return "驱动文件";
- case -255:
- return "绑定串口失败";
- case -254:
- return "第一次启动安装,必须以管理员权限运行";
- case -253:
- return "启动驱动服务失败";
- case -252:
- return "请检查Key是否有效";
- case -1:
- return "无效操作";
- case 0:
- return "成功";
- case 1:
- return "串口打开失败";
- case 2:
- return "串口配置失败";
- case 3:
- return "串口读取失败";
- case 4:
- return "串口写入失败";
- case 5:
- return "串口关闭失败";
- default:
- return "未知错误";
- }
- }
- bool ActiveXWrapper::IsPortMonitored(int port)
- {
- std::lock_guard<std::mutex> lock(mutex_);
- auto it = monitored_ports_.find(port);
- return it != monitored_ports_.end() && it->second;
- }
- SAFEARRAY *ActiveXWrapper::CreateSafeArrayFromBytes(const std::vector<BYTE> &bytes)
- {
- // 创建SafeArray来传递字节数组
- SAFEARRAYBOUND bounds[1];
- bounds[0].lLbound = 0;
- bounds[0].cElements = static_cast<ULONG>(bytes.size());
- SAFEARRAY *sa = SafeArrayCreate(VT_UI1, 1, bounds);
- if (!sa)
- {
- LOG_ERROR("Failed to create SafeArray");
- return nullptr;
- }
- // 将数据复制到SafeArray
- BYTE *data_ptr;
- HRESULT hr = SafeArrayAccessData(sa, reinterpret_cast<void **>(&data_ptr));
- if (SUCCEEDED(hr))
- {
- memcpy(data_ptr, bytes.data(), bytes.size());
- SafeArrayUnaccessData(sa);
- }
- else
- {
- LOG_ERROR("Failed to access SafeArray data");
- SafeArrayDestroy(sa);
- return nullptr;
- }
- return sa;
- }
- void ActiveXWrapper::Cleanup()
- {
- if (initialized_)
- {
- FreeMonitor();
- DisconnectEvents();
- if (activex_control_)
- {
- activex_control_->Release();
- activex_control_ = nullptr;
- }
- // 释放COM
- CoUninitialize();
- initialized_ = false;
- LOG_INFO("ActiveX control cleaned up");
- }
- }
|