Qt之調用C#的動態庫的解決方法

環境:VS2019+Qt5.12

1. CLR庫安裝

        首先,如果你VS2019沒有安裝CLR庫,那麼操作步驟為:

  • 打開 Visual Studio Installer
  • 在已安裝中點擊修改
  • 將使用C++的桌面開發的對V142(14.25)生成工具的C++/CLI支持
  • 點擊右下角的修改,安裝完成後重啟軟件即可

2. 新建類庫(.NET Framework)

註意:此處請確認選擇用於創建C#類庫(.dll)的項目

此時解決方案的視圖為:

一個簡單的測試直接在Class1.cs文件添加內容即可,此測試中隻修改此文件內容

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ClassLibrary1
{
    public class Class1
    {
        public Class1() { }
        public int myAdd(int a, int b)
        {
            int c = a + b + 5;
            return c;
        }
        public void mySub(int a, int b, ref int c)
        {
            c = a - b - 5;
        }
        public void mySetText(string text)
        {
            Console.WriteLine("ClassLibrary1的類名Class1下的mySetText: {0}", text);
        }
        public void myGetText(ref string text)
        {
            text = "ClassLibrary1的類名Class1下的myGetText";
        }
    }
}

編寫好瞭之後生成dll,將生成的dll復制到CLR的文件路徑下

3. 新建CLR類庫(.NET Framework)

此時解決方案的視圖為:

一個簡單的測試對應的頭文件ClassLibrary2.h修改即可,此測試中隻修改此文件內容

#pragma once
 
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
 
#using "./ClassLibrary1.dll"
 
using namespace ClassLibrary1;
 
extern "C" __declspec(dllexport) int MyAdd(int a, int b)
{
	ClassLibrary1::Class1 obj;
	return obj.myAdd(a, b);
}
extern "C" __declspec(dllexport) void MySub(int a, int b,int *c)
{
	ClassLibrary1::Class1 obj;
	return obj.mySub(a, b, *c);
}
 
extern "C" __declspec(dllexport) void MySetText(char* text)
{
	ClassLibrary1::Class1 obj;
	String^ str = gcnew String(text);
	obj.mySetText(str);
}
 
extern "C" __declspec(dllexport) void MyGetText(char** text)
{
	ClassLibrary1::Class1 obj;
	String^ str = gcnew String("");
	obj.myGetText(str);
	*text = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
}

這裡編寫完成後生成dll,然後非常重要的一步來瞭,將ClassLibrary1.dll、ClassLibrary2.dll、ClassLibrary2.lib準備復制到運行的Qt執行目錄下,如果沒有在同一個目錄下,在ClassLibrary2調用ClassLibrary1時會找不到ClassLibrary1.dll文件而報錯

4. Qt調用

4.1. 調用方法1

#include <QCoreApplication>
#include <windows.h>
#include <QDebug>
#include <QLibrary>
#include <QFile>
 
 
typedef int (*ADD)(int,int);
typedef void (*SUB)(int,int,int *);
typedef void (*SHOW)(QString);
int main(int argc, char *argv[])
{
    QLibrary mylib("ClassLibrary2.dll");  //聲明dll文件
    if (mylib.load())  //判斷加載是否成功
    {
        qDebug() << "DLL  loaded!";
        ADD add = (ADD)mylib.resolve("MyAdd"); //鏈接到add函數
        qDebug() << "add status: " << add;
        if (add){
            qDebug()<< "Link to add Function is OK!" << add(3,2) ;
        }
        SUB sub = (SUB)mylib.resolve("MySub");
        qDebug() << "sub status: " << sub;
        if (sub){
            int c = 10;
            sub(3,2,&c);
            qDebug()<< "Link to sub Function is OK!" << c;
        }
        SHOW show = (SHOW)mylib.resolve("MySetText");
        qDebug() << "show status: " << show;
        if (show){
            qDebug()<< "Link to show Function is OK!" ;
            const char *buf = "helloworld";
            show(buf);
        }
        qDebug()<< "DLL unload " << mylib.unload ();
    }
 
    else
    {
        qDebug()<< "DLL is not loaded!" ;
    }
    
    return 0;
}

4.2. 調用方法2

  • 右鍵項目->選擇添加庫->選擇外部庫
  • 在庫文件中找到剛才生成的ClassLibrary2.lib
  • 將平臺下的linux、Mac取消勾選
  • 將Windows下的所有都取消勾選

此時界面如下

extern "C" __declspec(dllexport) void MyGetText(char **p);
extern "C" __declspec(dllexport) void MySetText(char *p);
 
int main(int argc, char *argv[])
{
    MySetText(QString("helloworld").toUtf8().data());
    
    char* change_t=nullptr;
    MyGetText(&change_t);
    qDebug() << QString(change_t);
}

到此這篇關於Qt之調用C#的動態庫的文章就介紹到這瞭,更多相關Qt調用C#動態庫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: