Windows平台上使用Qt(MinGW)调用基于VS编写的周立功CAN卡Dll文件

以ZLG提供的智能Can卡dll(32bit)文件为例

​​一般情况下,在Windows平台上使用VS来编写的dll文件无法在Qt中使用中直接使用,需要在dll文件中进行一些特殊的声明。这里我们来介绍一下如何在Windows平台上使用Qt来调用致远电子生产的USB CAN卡dll库。

库函数文件总共有三个文件:ControlCAN.h、ControlCAN.lib、ControlCAN.dll 。

1. 首先我们创建好Qt项目以后需要打开*.pro文件,然后文件最后加入一个win32平台的dll声明:

win32: LIBS += -L$$PWD/./ -lControlCAN

2. 第二部需要将唯一的一个头文件ControlCAN.h添加到项目中。

3. 接下来我们需要在类mainwindow的头文件中加入一些新的定义,便于使用。这些函数是在“【使用手册】CAN测试软件与接口函数使用手册V3.11”中明确给出的,包括函数的参数等信息。

这里我们主要是使用typedef语句来重定义一些函数类型。为了便于讲解,这里我们以typedef DWORD(__stdcall VCI_ResetCAN)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);为例做进一步的解释:

Typedef语句的作用不做解释,我们来关注后边的部分。DWORD在最前面,后面为两对括号。

可以简写为

DWORD(函数名)(x,x,x)

很明显这个语句的作用就是使用VCI_ResetCAN来表示形参类型为(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd)的函数。实际上这个函数是CAN卡复位函数。

然后我们使用我们Typedef的VCI_ResetCAN来定义一个指针。这个指针指向了一个形参类型为(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd)。具体语句为:

   VCI_ResetCAN *pResetCAN;

可能很多人会想,还有一个词没有解释。至少我觉得很多人会这么想,因为这个关键字很少用。我就来解释一下__stdcall的作用吧,也不过多的解释。毕竟深究出来又是一大堆。__stdcall是用来告诉编译器,这里的函数调用方式为标准调用。因为不同的编译器调用函数的时候,调用方式是不一样的,如果还想有深入的了解,就去看看编译原理吧。

4.现在我们需要使用Qt提供的QLibrary类来解析dll文件。这个dll文件在ZLG提供的库函数文件夹 kerneldlls中。我们需要解析USBCAN.dll。

首先在添加头文件"QLibrary.h"到项目中,QLibrary的使用方法,请参考Qt官方文档,虽然是全英文的,但是很容易懂。然后装载USBCAN.dll文件。解析完成以后,解析函数返回一个函数指针。这里我们需要利用第三部中定义的指针。具体方式如下:

pResetCAN = (VCI_ResetCAN *)lib.resolve("VCI_ResetCAN");

pResetCAN是步骤3中定义的指针。(VCI_ResetCAN *)将函数返回的指针转换成特定形参的函数指针。lib.resolve("VCI_ResetCAN")是将USBCAN.dll中的函数VCI_ResetCAN解析出来。

好了,到这里我们已经将VCI_ResetCAN(DWORD DevType, DWORD DevIndex, DWORD CANIndex);函数从dll文件中调用出来。我们在使用的时候就可以使用

pResetCAN (DWORD DevType, DWORD DevIndex, DWORD CANIndex);

的形式进行使用。

下面我将部分代码贴出:

Mainwindow.cpp  

QLibrary lib("USBCAN.dll");

if(false==lib.load())

            QMessageBox::warning(this,"Warning","dll load ok");

    pOpenDevice = (VCI_OpenDevice *)lib.resolve("VCI_OpenDevice");

    pCloseDevice = (VCI_CloseDevice *)lib.resolve("VCI_CloseDevice");

    pInitCAN = (VCI_InitCAN *)lib.resolve("VCI_InitCAN");

    pStartCAN = (VCI_StartCAN *)lib.resolve("VCI_StartCAN");

    pTransmitCAN = (VCI_Transmit *)lib.resolve("VCI_Transmit");

    pReceive = (VCI_Receive *)lib.resolve("VCI_Receive");

    pGetReceiveNum = (VCI_GetReceiveNum *)lib.resolve("VCI_GetReceiveNum");

    pClearBuffer = (VCI_ClearBuffer *)lib.resolve("VCI_ClearBuffer");

    pReadErrInfoCAN = (VCI_ReadErrInfo*)lib.resolve("VCI_ReadErrInfo");

    pResetCAN=(VCI_ResetCAN *)lib.resolve("VCI_ResetCAN");

    pSetReference=(VCI_SetReference *)lib.resolve("VCI_SetReference");

    pReadBoardInfo=(VCI_ReadBoardInfo *)lib.resolve("VCI_ReadBoardInfo");

    pReadCANStatus=(VCI_ReadCANStatus *)lib.resolve("VCI_ReadCANStatus");

Mainwindow.h

typedef DWORD(__stdcall VCI_OpenDevice)(DWORD,DWORD,DWORD);

typedef DWORD(__stdcall VCI_ResetCAN)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_CloseDevice)(DWORD DeviceType,DWORD DeviceInd);

typedef DWORD(__stdcall VCI_InitCAN)(DWORD DeviceType, DWORD DeviceInd, DWORD CANInd, PVCI_INIT_CONFIG pInitConfig);

typedef DWORD(__stdcall VCI_StartCAN)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef ULONG(__stdcall VCI_Transmit)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pSend,ULONG Len);

typedef ULONG(__stdcall VCI_Receive)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_OBJ pReceive,ULONG Len,INT WaitTime/*=-1*/);

typedef ULONG(__stdcall VCI_GetReceiveNum)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_ClearBuffer)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd);

typedef DWORD(__stdcall VCI_ReadErrInfo)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_ERR_INFO pErrInfo);

typedef DWORD(__stdcall VCI_ReadCANStatus)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,PVCI_CAN_STATUS pCANStatus);

typedef DWORD(__stdcall VCI_SetReference)(DWORD DeviceType,DWORD DeviceInd,DWORD CANInd,DWORD RefType,PVOID pData);

typedef DWORD(__stdcall VCI_ReadBoardInfo)(DWORD DeviceType,DWORD DeviceInd,PVCI_BOARD_INFO pInfo);

    VCI_OpenDevice *pOpenDevice;

    VCI_ResetCAN *pResetCAN;

    VCI_CloseDevice *pCloseDevice;

    VCI_InitCAN *pInitCAN;

    VCI_StartCAN *pStartCAN;

    VCI_Transmit *pTransmitCAN;

    VCI_Receive *pReceive;

    VCI_GetReceiveNum *pGetReceiveNum;

    VCI_ClearBuffer *pClearBuffer;

    VCI_ReadErrInfo *pReadErrInfoCAN;

    VCI_ReadCANStatus *pReadCANStatus;

    VCI_SetReference *pSetReference;

    VCI_ReadBoardInfo *pReadBoardInfo;

Test.pro

win32: LIBS += -L$$PWD/./ -lControlCAN

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值