问题背景
我需要使用qt编写界面程序来操作设备,设备厂家提供了一个使用C#编写的dll库,里面包含了各种操作设备的函数。而我不想学习C#,使用C++来调用dll库的话,不论是显示调用(提供h文件,dll文件)、还是隐式调用(h、lib、dll),目前条件都不满足,经过查找资料,以下方法可以解决,特此记录。
条件配置
首先要确保自己的vs中有下图黄色部分的模块,如果没有,需下载
编写代码
在vs中创建下图所示的新项目
右键点击引用,将dll库引用进来,然后创建头文件,如下图所示:
#pragma once
using namespace System;
using namespace System::Reflection;
__declspec(dllexport) bool Connect_api(short iDevice) {
ImacFxDll::ImacFxDllT obj;
return obj.Connect(iDevice);
}
__declspec(dllexport) bool Close_api(short iDevice) {
ImacFxDll::ImacFxDllT obj;
return obj.Close(iDevice);
}
__declspec(dllexport) bool MoveDeviceToPos_api(short iDevice, short nAxis, double pos, double vel, bool isAbsolute) {
ImacFxDll::ImacFxDllT obj;
return obj.MoveDeviceToPos(iDevice, nAxis, pos, vel, isAbsolute);
}
__declspec(dllexport) bool SHome_api(short iDevice, short nAxis) {
ImacFxDll::ImacFxDllT obj;
return obj.SHome(iDevice, nAxis);
}
按alt + F7
调出项目属性选项
在配置类型中选择dll/lib,然后选择release,右键点击项目,选择生成。可以在文件夹中看到生成的lib和dll
qt配置1
因为qt默认使用的编译器是MinGW,而MinGW引用lib库的方式和MSVC有区别,具体为:
使用#pragma comment(lib, path) 这是 MSVC 专有的表达式
在mingw中是则不行,需要在Qt的pro文件中加入 LIBS += -lxxx 即可
比如:
msvc中:
#include <Shlwapi.h>
#pragma comment(lib, "C:/shlwapi.lib")
minGw:
pro文件添加:
LIBS += -lshlwapi
添加头文件:
#include <Shlwapi.h>
备注: mingw使用msvc的方式 会发出 warning: ignoring #pragma comment [-Wunknown-pragmas]
使用MSVC
如果需要将qt的编译套件更换为MSVC,打开qtcreator,点击工具——选项——kits,可以看到此时支持的构建套件,而我的qt在这个时候还不支持,配置方法如下:
- 打开Visual Studio installer
- 点击修改
- 将已勾选的组件更换为2017的组件,选择修改
此时我的qt貌似自动识别了msvc的组件
如果没有自动识别,可以在编译器中指定
问题1
在替换成msvc后出现了许多报错:main.cpp:96: error: cannot initialize object parameter of type ‘QWidget’ with an expression of type ‘MainWindow’,大致就是许多qt的组件相关的语句都红了
改正:在qtcreator中选择帮助(help)-关于插件(about plugins),将下图画框的选项取消勾选,就可以了
使用MinGW
右键点击项目名,引入库就行啦
qt编码
将cpp生成的lib库拷贝到qt工程的目录中
编写代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#pragma comment(lib, "D:/testdll/ImacFxCPP.lib")
__declspec(dllimport) bool Connect_api(short iDevice);
__declspec(dllimport) bool Close_api(short iDevice);
__declspec(dllimport) bool MoveDeviceToPos_api(short iDevice, short nAxis, double pos, double vel, bool isAbsolute);
__declspec(dllimport) bool MoveToPosByType_api(short iDevice, short nAxis, double fToStart, double fToEnd, double fToSpeed, double fStartEqu, double fEndEqu, double fStepPos, double fSpeed, double fDeltaStep, int iTime);
__declspec(dllimport) bool SHome_api(short iDevice, short nAxis);
__declspec(dllimport) bool Stop_api(short iDevice, short nAxis);
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ImacFxDllT Imac = new ImacFxDllT();
short iDevice = 0;
Imac.Connect(iDevice);
}
太麻烦了,还是用c#写了