WinAPI/MFC用户定义函数 我有一个简单的C++控制台应用程序,用来驱动色度计。 与设备接口的函数以MSVC DLL的形式提供,带有\uuu cdecl函数
我还得到了相应的WinAPI/MFC用户定义函数 我有一个简单的C++控制台应用程序,用来驱动色度计。 与设备接口的函数以MSVC DLL的形式提供,带有\uuu cdecl函数,c++,winapi,mfc,C++,Winapi,Mfc,我还得到了相应的.h和.lib文件。所有处理都依赖于需要在启动时实例化的事件处理程序。它从DLL函数中调用,以在数据准备好检索时发出警报。设备连接到USB端口,并在设备管理器(COM0)中显示为(虚拟?)COM端口 我需要将这个简单的应用程序“移植”到GUI环境中,以支持我的项目。我尝试了QtCreator 5.15.2(使用MinGW开源选项)和Embarcadero C++Builder,但是从这些环境访问DLL函数是不可能的。我尝试了wxWidget,但它对我来说“不起作用”——出于某种原
.h
和.lib
文件。所有处理都依赖于需要在启动时实例化的事件处理程序。它从DLL函数中调用,以在数据准备好检索时发出警报。设备连接到USB端口,并在设备管理器(COM0)中显示为(虚拟?)COM端口
我需要将这个简单的应用程序“移植”到GUI环境中,以支持我的项目。我尝试了QtCreator 5.15.2(使用MinGW开源选项)和Embarcadero C++Builder,但是从这些环境访问DLL函数是不可能的。我尝试了wxWidget,但它对我来说“不起作用”——出于某种原因,我无法让示例执行(找不到“Main/Invoke”)
所以我把注意力转向了MFC和WinAPI。创建一个C++ MFC应用程序是“直截了当”的,直到我必须“如何将我的设备接口”到这个系统。我尝试创建一个自定义类,myDevice
,以重新组合所有自定义函数,如“Connect”、“Calibrate”和“Measure”
在main.h
中,我声明该类:
class myDevice{
private:
//bool CalibratedStatus;
public:
bool Connect();
bool Calibrate();
bool Measure();
myDevice();
~myDevice();
};
然后在Main.cpp
中,我有成员函数定义:
MainApp::MainApp()
{
// TODO: add construction code here,
DEVICE_ERROR_TYPES deviceError = DEVICE_RegisterDeviceEventHandler(EventNotice);
// Place all significant initialization in InitInstance
}
myDevice::MyDEVICE() { }
myDevice::~MyDEVICE() { }
bool myDevice::Connect() {
string StatusDEVICE;
uint8 StateTableRB, portInfoName, portInfoSerialNo;
string DevicePortList;
uint32 portCount = 0;
DEVICE_PortInfo portInfo[16];
uint8 StateTable[2][4] = { "Eth", "USB" };
// "01 Looking for the instrument...
DEVICE_GetDevicePortList(0, &portCount, 0);
if (portCount > 16) {
portCount = 16;
}
else if (portCount < 1) {
// printf("device not found\n");
return false;
}
DEVICE_GetDevicePortList(portInfo, &portCount, portCount); // display device list
deviceError = DEVICE_Connect(&portInfo[0], 10);
if (DEVICE_SUCCESSFUL(deviceError)) {
StatusDEVICE = "Device Connect Complete!";
// printf("Device Connect Complete!\n");
return true;
}
}
bool myDevice::Calibrate() { }
bool myDevice::Measure() {
if (CalibratedStatus == true) {
// Set measure condition
DEVICE_MeasureCondition measureCondition = { measureType, 0 };
deviceError = DEVICE_SetMeasureCondition(&measureCondition);
// start measurement
deviceError = DEVICE_StartMeasurement();
if (device_SUCCESSFUL(deviceError)) {
while (!isMeasureWait) {
if (isDisConnect) break;
// waiting for measurement complete
this_thread::sleep_for(chrono::milliseconds(1000));
}
ExportMeasureData(measureType);
isMeasureWait = true;
return true;
}
else return false;
}
}
我将其放置在MainApp::MainApp()
行(全局?)上方
我承认我对MFC或WiNAPI没有任何编码经验,但是我有一个预感,它与在一个源文件中间声明一个事件处理程序和后面的一组松散的函数来检索数据有很大的不同。 不知何故,我不清楚像这些“策略性”的“用户定义函数”可以放在哪里?并调用它们?如果我在按钮处理程序中创建一个按钮,比如说“连接”到设备,很容易将连接到设备的代码放在那里并从那里执行。但是“返回”呢"? 因为返回不是“直接的”(可能是“异步的”);返回总是采用事件处理程序的路径,并到达事件通知中,在那里我有一个Switch语句,它将任务重定向到与“接收到的事件”对应的函数。我无法改变这种行为
我正在阅读有关串行通信应用程序的文章,据我所知,这些应用程序使用MFC中的“串行事件”来触发对函数的调用?但这对我来说真的是“新鲜”。我不确定这是否是一个好方法?正如您在上面的代码中所看到的,有一个“线程睡眠”在“设备忙时”执行?一旦设备完成,它将使用其响应自行调用事件通知处理程序:void EventNotice(DEVICE_EventCode outEventCode, uint32 outRAWDataCount, DEVICE_ERROR_TYPES outError)
{
switch (outEventCode) {
case Event_Standby: // 0
// cout << "Standby..." << endl;
break;
case Event_MeasureWait: // 1
if (isMeasureCompleted) {
// export measure data
// printf("\n04 Export Measure Data...");
ExportMeasureData(measureType);
isMeasureWait = true;
case ...
很抱歉,我不能清楚地说明您的问题是什么,请您在没有私人信息的情况下展示一下好吗?基本上,我想知道如何从过程编程方法过渡到基于消息的方法?我将尝试找出一些错误消息…好的,当我运行代码时,我得到这个未解析的外部符号:\u DEVICE_RegisterDeviceEventHandler@4在函数“public:u thiscall CMainApp::CMainApp(void)”中引用(??0CMainApp@@QAE@XZ)我怀疑链接器找不到我的设备DLL函数?可能(我不是专家)是因为“错误”的调用约定,正如我所看到的,出于某种原因,当所有DLL函数都以uuu cdecl作为前缀时,链接器希望使用uu thiscall“前缀”?否则,我的问题的要点是“我是否从一个好的角度来处理这个问题?”这个错误是说链接器找不到您自己的代码从
CMainApp::CMainApp()
内部调用的DEVICE\u RegisterDeviceEventHandler()
函数。听起来你没有在你的项目中包含DLL的.lib
导入文件,或者它与你的构建工具不兼容。另外,“我试过…Embarcadero C++Builder,但是…访问DLL函数是不可能的”-我觉得很难相信。特别是如果DLL是用C接口设计的,就像这样。它应该可以在任何C/C++编译器中工作,包括C++Builder。多年来,我在C++Builder中使用了许多基于C的DLL,它们工作得很好。有时(通常),我只需要使用C++Builder的IMPLIB
或MKEXP
工具生成一个新的导入库,因为大多数DLL供应商不为C++Builder提供.lib
文件。有时(很少),我必须对DLL的.h
文件进行调整。
void EventNotice(DEVICE_EventCode outEventCode, uint32 outRAWDataCount, DEVICE_ERROR_TYPES outError)
{
switch (outEventCode) {
case Event_Standby: // 0
// cout << "Standby..." << endl;
break;
case Event_MeasureWait: // 1
if (isMeasureCompleted) {
// export measure data
// printf("\n04 Export Measure Data...");
ExportMeasureData(measureType);
isMeasureWait = true;
case ...
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
91 number of functions
91 number of names
ordinal hint RVA name
60 0 0003E2F0 DEVICE_Calculate
61 1 0003DA60 DEVICE_Calibrate
62 2 0003DE10 DEVICE_Cancel
63 3 0003D7D0 DEVICE_Connect
64 4 0003D8E0 DEVICE_Disconnect