C#调用Qt编写的带界面的dll

时间:2024-03-19 08:43:47

C#调用Qt编写的带界面的dll


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013482632/article/details/88829072

Qt编写带界面的dll

Qt编写的带界面的dll程序,由于Qt必须调用QApplication的exec方法才能运行,所以在普通windows程序中是不能调用的,Qt提供了解决方案qtwinmigrate

  1. 开发环境
    操作系统:win10
    Qt Create版本:qt-creator-opensource-windows-x86-4.4.1.exe,下载地址:http://download.qt.io/archive/qt/4.8/4.8.6/
    qtwinmigrate源码:从https://github.com/qtproject/qt-solutions下载的qtwinmigrate源码。
  2. 操作流程
    1)从qtwinmigrate/examples中复制一份qtdll,重命名,比如“testdll”,文件夹里有一份main.cpp和pro文件;
    2)用Qt Creator打开“testdll”下的pro文件,添加自己写的界面类文件,在pro文件中添加这些文件;
    3)release模式下构建工程,会在qtwinmigrate\examples\build-testdll-unknown-Release\release文件夹下生成对应dll文件,该文件即可被C#程序调用。
  3. 代码演示
    1)自己界面类构造函数
CTestDialog(HWND hParentWnd, QObject *parent = 0, Qt::WindowFlags f = 0);
CTestDialog::CTestDialog(HWND hParentWnd, QObject *parent, Qt::WindowFlags f)
	:QDialog(0, f), hParent(hParentWnd)
{
	if (parent)
        QObject::setParent(parent);
}

2)main.cpp

#include <qmfcapp.h>
#include <windows.h>
#include "testDialog.h"//include自己的界面类文件

BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpvReserved*/ )
{
    static bool ownApplication = FALSE;

    if ( dwReason == DLL_PROCESS_ATTACH )
        ownApplication = QMfcApp::pluginInstance( hInstance );
    if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
        delete qApp;

    return TRUE;
}

// char* output用于给调用者返回数据,如:CTestDialog界面配置结果等
extern "C" __declspec(dllexport) bool showDialog( HWND parent, char* output )
{
    std::string ret = "";
    CTestDialog dialog(parent);
    if (dialog.exec() == QDialog::Accepted)
        ret = dialog.getResults();//dialog配置结果

    strcpy_s(output, ret.length()+1, ret.c_str());
    return TRUE;
}

注意
1)需要将调用接口导出(extern “C” __declspec(dllexport));
2)如果调用的界面仅用于展示,不需要返回数据时,showDialog可采用如下实现方式:

extern "C" __declspec(dllexport) bool showDialog( HWND parent )
{
      CTestDialog dialog(parent);
      dialog.show();
      return qApp->exec();
}

3)注意字符串的传递需要采用char*方式。

C#调用实现

  1. 开发环境
    操作系统:win10
    开发工具:VS2010
  2. 操作流程
    1)新建项目,Visual C#–Windows,选择Windows窗体应用程序,修改项目名称和存储位置;
    2)修改Form1.cs文件,引用构建的Qt的testdll.dll,运行即可出效果。
  3. 代码演示
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;   //必须添加,不然DllImport报错

namespace WindowsFormsTest
{
    public partial class Form1 : Form
    {
    	//"testdll\testdll.dll"是testdll.dll路径,可以是绝对路径和相对路径
        [DllImport(@"testdll\testdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
        //output为testdll.dll返回的char*
        public static extern bool showDialog(IntPtr parent, ref byte output);

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            byte[] data = new byte[100];
            bool ret = showDialog(this.Handle, ref data[0]);
            string strGet = System.Text.Encoding.Default.GetString(data, 0, data.Length);
            Console.WriteLine(strGet);//用vs运行时,strGet打印在VS的输出窗口中
        }
    }
}

注意
1)Qt编写的dll文件移动位置时,需要将其依赖的库都拷出来一起移动,尤其是换了电脑之类的,否则运行将不成功。可用DEPENDS工具查看其依赖的库;
2)本处只演示了C#语言调用,C++调用时需要LoadLibary等,此处不再演示,读者可自行实验。

结果

运行C#程序后,界面弹出Qt编写的CTestDialog界面,如下图所示,涉及项目内容处均涂红了。
C#调用Qt编写的带界面的dll
点击弹出的dialog的“确定”按钮时,测试程序中返回的字符串“test”打印在VS的输出窗口中,下图中红框框起来的部分,蓝色部分涉及个人信息,所以涂蓝了。
C#调用Qt编写的带界面的dll