欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Qt之调用C#的动态库的解决方法

程序员文章站 2022-03-03 08:39:53
环境:vs2019+qt5.121. clr库安装首先,如果你vs2019没有安装clr库,那么操作步骤为: 打开 visual studio installer 在已安装中点击修改...

环境:vs2019+qt5.12

1. clr库安装

        首先,如果你vs2019没有安装clr库,那么操作步骤为:

  • 打开 visual studio installer
  • 在已安装中点击修改
  • 将使用c++的桌面开发的对v142(14.25)生成工具的c++/cli支持
  • 点击右下角的修改,安装完成后重启软件即可

2. 新建类库(.net framework)

注意:此处请确认选择用于创建c#类库(.dll)的项目

此时解决方案的视图为:

Qt之调用C#的动态库的解决方法

一个简单的测试直接在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)

此时解决方案的视图为:

Qt之调用C#的动态库的解决方法

一个简单的测试对应的头文件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下的所有都取消勾选

此时界面如下

Qt之调用C#的动态库的解决方法

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#动态库内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

相关标签: Qt C# 动态库