这篇文章主要介绍了Qt程序中调用C#编写的dll,本文图文并茂给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
1、打开Visual Studio,新建一个C#的Class Library项目(这里选择的是.Net Framework 4),项目名为CSharpDll。
2、由于默认没有引入Forms等UI库,先在reference中添加引用System.Windows.Forms
以便可以在测试中使用MessageBox
等。
3、最终C#编写的dll的源代码如下图所示,命名空间为CSharpDll,公共类为CSharpClass。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace CSharpDll
{
public class CSharpClass
{
public CSharpClass() { }
public int add(int a , int b)
{
return a + b;
}
public void substract( int a , int b , ref int c)
{
c = a - b;
}
public static void showBox(string str)
{
MessageBox.Show("C#:" + str);
}
}
}
里面包含一个加法add,一个减法substract(为了测试指针,所以在减法的返回类型是void,而把计算结果通过ref参数c给返回),一个showBox方法(里面采用C#的MessageBox对话框显示用户输入的参数字串)
4、对project进行release build,在release目录下生成了CSharpDll.dll
(待会用到)。
5、关闭CSharpDll项目,另外新建一个C++ CLR类型的Class Library项目(选择与C#项目相同的.Net Framework 4),项目名称为CppDll。
一开始我用的VS2019,发现VS2019好像无法新建 C++ CLR类型的Class Library项目了,所以学习微软的技术一定要小心,学习主流的支持很久的技术,尽量不要学习新出的技术,如果必须学新技术,一定要认真考量,一些边缘化的技术一定不要学习,没准哪天微软就不维护了。
6、选择Project->CppDll Properties…,在弹出的属性页面选择“Add New Reference..”,点击“browsing.”后选择CSharpDll项目中release目录下的CSharpDll.dll。
7、选择CSharpDll.dll后,可以看到在项目属性的References中出现了CSharpDll这个Library。
8、在CppDll项目中的CppDll.h中利用 _declspec(dllexport)
导出对应的3个接口函数add,substract,showBox 。需要using namespace System::Reflection,对于这里的showBox,其参数不能采用CSharpDll里面的showBox参数的String类型,而是使用const char* 类型。
主要代码如下所示:
// CppDll.h
#pragma once
using namespace System;
using namespace System::Reflection;
__declspec(dllexport) int add(int a, int b)
{
CSharpDll::CSharpClass obj;
return obj.add(a, b);
}
__declspec(dllexport) void substract(int a, int b, int *c)
{
CSharpDll::CSharpClass obj;
obj.substract(a, b, *c);
}
__declspec(dllexport) void showBox(const char* content)
{
CSharpDll::CSharpClass obj;
String^ str = gcnew String(content);
obj.showBox(str);
}
namespace CppDll {
public ref class Class1
{
// TODO: 在此处添加此类的方法。
};
}
9、选择release方式build CppDll项目,在release文件夹中生成了CppDll.dll文件,可以看到同时其也将引用的CSharpDll.dll也给拷贝到release文件夹中了。
10、接下来在Qt中进行调用, 在QtCreator中新建一个TestCSharpDll GUI项目,编译器选的mingw。通过VS自带的命令行工具中的dumpbin工具可以查看CppDll.dll导出的函数接口。
dumpbin -exports (+dll路径)
在TestCSharpDll工程中通过typedef定义函数指针,同时采用QLibrary动态加载并resolve函数。
在这里.dll的路径设为当前目录下“./CppDllMingW.dll”,也就是编译好的程序exe同一目录下的dll,去resolve由普通导出方式的接口即“?add@@YAHHH@Z”。
主要代码如下所示:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QLibrary>
#include<QMessageBox>
typedef int (*x_add)(int a , int b);
typedef void (*x_substract)(int a , int b , int* c);
typedef void (*x_showBox)(const char* content);
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
//add
void MainWindow::on_pushButton_clicked()
{
int a = ui->lineEdit->text().toInt();
int b = ui->lineEdit_2->text().toInt();
QLibrary library("./CppDll.dll");
if(library.load()){
x_add add = (x_add)library.resolve("?add@@YAHHH@Z");
if(add){
QString str = QString::number(add(a , b));
QMessageBox::information(this , "call add from dll" , str);
}
}
}
//sub
void MainWindow::on_pushButton_2_clicked()
{
int a = ui->lineEdit_3->text().toInt();
int b = ui->lineEdit_4->text().toInt();
int c = 0;
QLibrary library("./CppDll.dll");
if(library.load()){
x_substract sub = (x_substract)library.resolve("?substract@@YAXHHPAH@Z");
if(sub){
sub(a , b , &c);
QString str = QString::number(c);
QMessageBox::information(this , "call sub from dll" , str);
}
}
}
//showBox
void MainWindow::on_pushButton_3_clicked()
{
QLibrary library("./CppDll.dll");
if(library.load()){
x_showBox showBox = (x_showBox)library.resolve("?showBox@@YAXPBD@Z");
if(showBox){
showBox("showBox!");
}
}
}
编译TestCSharpDll工程,将CppDll.dll和CSharpDll.dll复制到同一目录下,执行TestCSharpDll.exe,可看出点击按钮后,通过QLibrary进行动态resolve,均正常调用。
最好是将相关dll置于同一目录下运行,不然会出现“未能加载文件或程序集”的异常。针对.lib链接方式,理应是置于同一目录下。而针对QLibrary进行resolve方式,可能通常一开始的想法是,CppDll.dll和CSharpDll.dll放在与程序不同目录的地方,程序中利用了QLibrary指定了CppDll.dll的方式进行加载,而CppDll.dll和CSharpDll.dll,因此程序调用CppDll.dll里面的函数时,CppDll.dll会找到与CppDll.dll同一目录下的CSharpDll.dll,然而CppDll.dll在被程序进行加载时,其继承了程序的环境变量,因此会从程序的当前目录下去查找,所以最好还是将CppDll.dll和CSharpDll.dll放置于程序同一目录下,同时QLibrary加载当前目录下的CppDll.dll。当然,部署到另外一台机器上时,目标机器还是需要安装.Net Framework,其版本至少不能低于当前CSharpDll.dll所使用的版本。
总结
到此这篇关于Qt程序中调用C#编写的dll的文章就介绍到这了,更多相关Qt 调用C#编写的dll内容请搜索得得之家以前的文章希望大家以后多多支持得得之家!
本文标题为:Qt程序中调用C#编写的dll(推荐)
基础教程推荐
- C#类和结构详解 2023-05-30
- linux – 如何在Debian Jessie中安装dotnet core sdk 2023-09-26
- C# windows语音识别与朗读实例 2023-04-27
- C#控制台实现飞行棋小游戏 2023-04-22
- unity实现动态排行榜 2023-04-27
- ZooKeeper的安装及部署教程 2023-01-22
- C# 调用WebService的方法 2023-03-09
- 一个读写csv文件的C#类 2022-11-06
- winform把Office转成PDF文件 2023-06-14
- C# List实现行转列的通用方案 2022-11-02