C#调用C++封装的SDK库(dll动态库)——上

C#调用C++封装的SDK库(dll动态库)——上

一、C++封装库

通过前几篇文章,我们封装了C++的动态DLL库,有Qt版的,有C++版的,当然还有介绍了Pimpl模式在SDK封装中的使用:

Qt创建SDK

VS创建SDK

Pimple在SDK封装中的应用

但是,我遇到了一个场景:需要把VS创建的DLL动态库,给C#代码来调用(并且我的动态库中还包含我的计算类)。本篇文章就介绍如何来封装,并提供调用。

 二、C#调用的方式

我们C++的项目里,经常是把算法单独封装为一个类供其他的类来调用的,这样也方便管理,但是如果我们写的这个C++算法类要封装成动态DLL库,供C#代码来调用,这时候就不能直接调用了,我们知道C#和C++时两种语言,要想让C#调用C++的库,这时候只要有个中间桥梁不久可以了。

对于此,微软提供了2种调用dll的方式,托管非托管

对于托管和非托管,可以这样简单的理解托管就是内存管理由系统管理,而不是由程序员自己来管理。而C++本身的内存管理是由程序员来控制的。

C#编写的是托管代码,所以微软提供了托管C++,托管C++用于微软的 Common Language Runtime (CLR) .NET开发,这种特殊的C++语法能够使C++程序员进行.NET开发,而不需要学一门像C#这样的新语言。托管C++和C#的特性一样,只是编程风格与C++类似,这也是微软兼顾不同语言之间的交互而做的。

而使用非托管C++的方法就是使用DllImport的方法来调用,其中DLL文件时用C语言编写的。

本片主要介绍通过非托管的方式封装动态dll库,并使用C#调用

三、封装C语言风格的库

1、我们创建一个DLL的动态库工程,命名CalculationDLL。

 

 

在项目中添加一个Calculation类。

 

 Calculation.h头文件添加如下代码:

#pragma once

#ifdef DLLCALCULATION_EXPORTS
#define DLLCALCULATION_API __declspec(dllexport)
#else
#define DLLCALCULATION_API __declspec(dllimport)
#endif // DLLCALCULATION_EXPORTS


class Calculation
{
};

EXTERN_C DLLCALCULATION_API int add(int a, int b);

EXTERN_C DLLCALCULATION_API int subtract(int a, int b);

EXTERN_C DLLCALCULATION_API int multiply(int a, int b);

EXTERN_C DLLCALCULATION_API int divide(int a, int b);

Calculation.cpp文件添加如下代码:

#include "pch.h"
#include "Calculation.h"

DLLCALCULATION_API int add(int a, int b) 
{
	return (a + b);
}

DLLCALCULATION_API int subtract(int a, int b)
{
	return (a - b);
}

DLLCALCULATION_API int multiply(int a, int b)
{
	return (a * b);
}

DLLCALCULATION_API int divide(int a, int b)
{
	return (a / b);
}

在属性页,C/C++->预处理器->预处理器定义,添加DLLCALCULATION_EXPORTS

 四、创建C#控制台调用

创建一个C#的控制台项目:

 

 

 在Program.cs中输入下面的调用代码:

// See https://aka.ms/new-console-template for more information

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;

namespace ConsoleApp1
{
    class Program
    {
        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int add(int a, int b);
                [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int subtract(int a, int b);

        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int multiply(int a, int b);

        [DllImport("C:\\My_vs2022Project\\CalculationDLL\\x64\\Release\\CalculationDLL.dll", CallingConvention = CallingConvention.Cdecl)]
        public extern static int divide(int a, int b);

        static void Main(string[] args)
        {
            int a = 10;
            int b = 2;
           Console.WriteLine("a+b= " + add(a,b) );
            Console.WriteLine("a-b= " + subtract(a, b));
            Console.WriteLine("a*b= " + multiply(a, b));
            Console.WriteLine("a/b= " + divide(a, b));
            Console.WriteLine("calc end.");
            Console.ReadKey();
        }
    }
}

五、运行

运行结果如下:

 

通过以上的过程,我们封装的相当于C语言风格的代码,如果我们要是有个C++的类呢?就像代码中Calculation类,上面是个空类,如果add、subtract等函数时类Calculation的成员函数时,我们该怎么封装呢,你可以思考一下,咱们下一篇继续。

上一篇:VS2022中创建C++SDK库(dll动态库)并调用SDK库(dll动态库)

下一篇:

本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冯一川

谢谢老板对我的支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值