Qt调用Matlab库C#库dll调用C++调用C#库CSharp库lib invoke matlab library .net donet netframework

Qt调用Matlab库C#库dll调用C++调用C#库CSharp库lib invoke matlab library .net donet netframework


该文章是一篇说明c++/Qt调用C#库的例子及代码,主要是本人在工作中尝试调用C#过程中,出现了很多的问题,以至于花了很长时间才有些头绪,这也是为了帮助即将有此需求的您,也是为了记录我的操作过程,以便下次不再花费长时间。
我整个过程是使用Matlab转.net库,CLI接口调用Matlab库,使用的是vs2019,matlab2022,Qt5.14.2,windows10系统。所有的代码只是为了测试使用,请根据自己需求修改。该过程中包含算法输入输出的转换方法,这也是过程中的重点所在。
废话少说,开始吧。。。
1、Matlab代码

function [doubleArg, stringArg] = MyAlgoTest(doubleArg1 ,doubleArg2, stringArg3)
%MYALGOTEST 此处显示有关此函数的摘要
%   此处显示详细说明

doubleArg = doubleArg1 + doubleArg2;
stringArg = stringArg3 + "_Matlab";

end

2、deploytool命令转换为.net库
在这里插入图片描述

3、建立C#工程,并加入上面生成的matlab库,和Mwarray库
在这里插入图片描述
C#代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using MyAlgoTest;
using MathWorks.MATLAB.NET.Arrays;

namespace LibCSAlgo
{
    public class CSClass
    {
        //function [doubleArg, stringArg] = MyAlgoTest(doubleArg1 ,doubleArg2, stringArg3)
        public string InvokeMatlabAlgo(double arg1, double arg2, string arg3, out double outArg1, out string outArg2)
        {
            string error = "";

            System.Console.WriteLine("ARG1 = ", arg1);
            System.Console.WriteLine("ARG2 = ", arg2);
            System.Console.WriteLine("ARG3 = ", arg3);

            TestClass c = new TestClass();
            MWArray[] outData = c.MyAlgoTest(2, arg1, arg2, arg3);

            outArg1 = (double)(MWNumericArray)outData[0];
            outArg2 = outData[1].ToString();

            System.Console.WriteLine("outArg1 = ", outArg1);
            System.Console.WriteLine("outArg2 = ", outArg2);

            return error;
        }

    }
}

4、建立CLR库工程,如果无此选项,需要通过vs安装程序安装CLI支持
在这里插入图片描述
5、CLR库代码

#include "pch.h"

#include "LibCLRWapper.h"

#include <msclr/marshal_cppstd.h>
#include <iostream>

#using "LibCSAlgo.dll"

using namespace LibCSAlgo;
using namespace System;
using namespace System::IO;
using namespace msclr::interop;

gcroot<CSClass^>* g_csclass = new gcroot<CSClass ^>; //全局变量定义
//CSClass^ g_csclass = gcnew CSClass; //不能使用此方法定义全局托管变量,报错

LibCLRWapper::CLRClass::CLRClass()
{
	*g_csclass = gcnew CSClass();
}

std::string LibCLRWapper::CLRClass::InvokeMyAlgo(double arg1, double arg2, const char* arg3, double& oArg1, char** oArg2)
{
	System::String^ outString_ = gcnew System::String("");
	System::String^ stringArg = gcnew System::String(arg3);
	double outDouble = 0;

	System::String^ outData = (*g_csclass)->InvokeMatlabAlgo(arg1, arg2, stringArg, outDouble, outString_);

	int stringLen = outString_->Length;
	std::string oo = marshal_as<std::string>(outString_);
	memcpy(*oArg2, oo.c_str(), stringLen);

	oArg1 = outDouble;
	std::cout << "\n\nThis is CLR:" << std::endl;
	std::cout << "outDouble:" << outDouble<< std::endl;
	std::cout << "outString:" << oo << std::endl;

	outData = "No Error";
	return marshal_as<std::string>(outData);
}
#pragma once

#include <string>

//不要在此h文件中using namespace 有关c#的空间,因此可能会与windows.h的空间冲突,建议只在cpp中using

# if defined LIB_CLRLibrary
#  define CLRLIBRARY_EXPORT __declspec(dllexport)
# else
#  define CLRLIBRARY_EXPORT __declspec(dllimport)
# endif


namespace LibCLRWapper {
	/*public ref*/ class CLRLIBRARY_EXPORT CLRClass
	{
	public:
		CLRClass();

		std::string InvokeMyAlgo(double arg1, double arg2, const char* arg3, double& oArg1, char** oArg2);

	};
}

此工程需要在预处理中加入导出宏,以及添加“引用”第3步建立的C#库
在这里插入图片描述
using *.dll的目录可以写绝对路径或者相对路径,否则可能找不到
在这里插入图片描述
6、QT工程,带界面,点击按钮执行

void QTinvokeCSMatlab::on_pushButton_invoke_clicked(void)
{
    qDebug() << "invoke start" << endl;

    if (m_clrclass)
    {
        //std::string InvokeMyAlgo(double arg1, double arg2, char* arg3, double& oArg1, char** oArg2);
        double arg1 = 10;
        double arg2 = 20;
        QString arg3 = "Test";
        double oArg1 = 0;
        std::string oArg2 = "";
        char * oArg2_ = new char[128];
        memset(oArg2_, 0, 128);

        char arg3_[128] = { 0 };
        memset(arg3_, 0, 128);
        memcpy(arg3_, arg3.toLatin1(), arg3.length());
        //
        std::string outData = m_clrclass->InvokeMyAlgo(arg1, arg2, arg3.toStdString().c_str(), oArg1, &oArg2_);

        std::string o2(oArg2_);
        if (oArg2_)
        {
            delete oArg2_;
            oArg2_ = nullptr;
        }

        qDebug() << "\n\nThis is  QT:";
        qDebug() << "oArg1 = " << QString::number(oArg1);
        qDebug() << "oArg2 = " << o2.c_str() << endl;
        qDebug() << "outData = " << outData.c_str();
    }

    qDebug() << "invoke over" << endl;
    QMessageBox::information(this, QString("Info"), QString("Over"));
}

到此,代码已经全部完成。
在这里插入图片描述
其中CLR既可以使用C#的语法也可以使用C++语法,只是new的表示方法有点区别,主要还是要注意输入输出的变量,以及不同语言之间的编码问题,可能会使得结果不正确或者乱码,至少我写的例子中不会出现,默认就好了。
执行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值