• C#如何调用C++(进阶篇)


    上一篇文章最后,提出的一个问题:如果一个c++库中有很多方法,需要一个个声明??这样岂不是要写很多代码??,而且没有智能提示看到提供了那些方法。

    如下图:

     如果有朋友需要用这种方式调用,而又不知道怎么使用,请看我的上一篇文章:https://www.cnblogs.com/skyfreedom/p/11773597.html

    针对上述问题,在使用过程中总结,记录下来,供需要的朋友参考。

    重点:通过CLI实现c#调用c++

    看完了本文,相信你就会了,一步步操作就是了。

    一、 新建一个netcore控制台应用程序;

    这个是我们测试调用C++用的

    二、 创建一个c++空项目

    如图:

     项目创建完成,我们添加一个类,写几个方法,这儿就简单写一个计算器的加减乘除吧!

    在CaculateData.h中添加如下代码,定义几个函数声明;

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    
    #ifdef CaculateDLL_EXPORTS
    #define Calculate_EXPORTS __declspec(dllexport)
    #else
    #define Calculate_EXPORTS __declspec(dllimport)
    #endif
    
    extern "C" Calculate_EXPORTS int Add(int numberA, int numberB);
    
    extern "C" Calculate_EXPORTS int Subtract(int numberA, int numberB);
    
    extern "C" Calculate_EXPORTS int Multiplication(int numberA, int numberB);
    
    extern "C" Calculate_EXPORTS  int Divided(int numberA, int numberB);
    
    class CaculateData
    {
    public:
        CaculateData();
        ~CaculateData();
    
    };

    可以看到,#ifdef的宏没有定义,所以我们需要添加一个宏:

    项目右键---属性---配置属性---C/C++---预处理器---预处理器定义,将定义的宏添加进去;

    可以看到,定义好了,颜色就变成紫色的,说明已经声明了宏;

    在CaculateData.cpp中实现这几个方法;

    #include "CaculateData.h"
    #include <iostream>
    
    CaculateData::CaculateData()
    {
    }
    
    
    CaculateData::~CaculateData()
    {
    }
    
    Calculate_EXPORTS int Add(int numberA, int numberB)
    {
        return numberA + numberB;
    }
    
    Calculate_EXPORTS int Subtract(int numberA, int numberB)
    {
        return numberA - numberB;
    }
    
    Calculate_EXPORTS int Multiplication(int numberA, int numberB)
    {
        return numberA * numberB;
    }
    
    Calculate_EXPORTS int Divided(int numberA, int numberB)
    {
        if (numberB == 0) {
            std::cout << "除数不能为空" << std::endl;
        }
        return numberA / numberB;
    }

    修改C++工程项目输出目录,这儿主要是便于CLI引用,我们这儿同意定义到Testinvoking项目的输出目录..inDebug etcoreapp2.2

    (修改步骤:项目右键—属性—配置属性—常规—输出目录)

    配置类型修改为:动态库.dll

    (修改步骤:项目右键—属性—配置属性—常规—配置类型)

     然后生成;

    结果如下:可以看到,日志已经打印出来,告知我们生成成功了。

     去对应目录看一下,也OK

    三、新建一个CLR项目

    这个项目就是来实现C#调用C++的

    因为需要调用Caculate.dll,所以需要引用它;

    配置属性—VC++目录—库目录(把刚刚生成Caculate.dll的路径添加进去)

     同时引用库:

     添加一个类InvokeCon.cpp,用它来调用Caculate.dll中的方法

     InvokeCon.cpp代码如下:

    #include "InvokeCon.h"
    
    InvokeCon::InvokeCon()
    {
    }
    
    int InvokeCon::AddCli(int numberA, int numberB)
    {
        return Add(numberA, numberB);
    }
    
    int InvokeCon::SubtractCli(int numberA, int numberB)
    {
        return Subtract(numberA, numberB);
    }
    
    int InvokeCon::MultiplicationCli(int numberA, int numberB)
    {
        return Multiplication(numberA, numberB);
    }
    
    int InvokeCon::DividedCli(int numberA, int numberB)
    {
        return Divided(numberA, numberB);
    }

    InvokeCon.h代码:

    #pragma once
    
    #include <iostream>
    #include "C:Users	jysource
    eposTestInvokingCaculateCaculateData.h"//引用库声明对应文件路径
    public ref class InvokeCon
    {
    public:
        InvokeCon();
    
        int AddCli(int numberA, int numberB);
        int SubtractCli(int numberA, int numberB);
        int MultiplicationCli(int numberA, int numberB);
        int DividedCli(int numberA, int numberB);
    };

    然后编译,修改编译类型为动态库dll

     然后生成:此时就产生了CliDll.dll库

    四、c#通过引用CliDll.dll来调用Caculate中的方法

    1、添加对Dll的引用;

    2、在C#项目中添加测试代码:

    可以看到,此时就能够调用多个方法,而且会有方法名提示!

    using System;
    
    namespace TestInvoking
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                try
                {
                    Console.WriteLine("---------c#通过CLI调用C++类方法---------");
                    Console.Write("请输入numberA:");
                    int numberA = Convert.ToInt32(Console.ReadLine());
                    Console.Write("请输入numberB:");
                    int numberB = Convert.ToInt32(Console.ReadLine());
    
                    InvokeCon invoke = new InvokeCon();
                    int addResult = invoke.AddCli(numberA, numberB);
                    int subResult = invoke.SubtractCli(numberA, numberB);
                    int mutilResult = invoke.MultiplicationCli(numberA, numberB);
                    int divResult = invoke.DividedCli(numberA, numberB);
    
                    Console.WriteLine($"the {numberA} And {numberB} sum is:{addResult};sub is:{subResult};Mutil is:{mutilResult};div is:{divResult}");
                }
                catch(Exception ex)
                {
                    Console.WriteLine($"ex:{ex}");
                }
    
                Console.WriteLine("执行成功");
                Console.ReadLine();
            }
        }
    }

     OK,完成!

    代码已经放到了github,需要的朋友可以去看,就是这篇文章简单的demo:

    github地址:https://github.com/tomorrowGooddays/Invoke

    说明:操作过程中有任何问题可以留言讨论,写错不易,欢迎纠正!原创文章,转载请说明出处,谢谢!

  • 相关阅读:
    Docker+Nginx 部署Vue+Element前端项目
    MySql取字段逗号分隔的第一个
    Mysql数据库中从表字段中存储了主表以逗号隔开的主键ID,现需求查询从表数据以及以逗号隔开的字段改为主表名称隔开(group_count() find_in_set())
    IIS 错误500.21解决方法
    IIS 出现500.19 错误处理解决方式
    Linux中vim的三种模式
    Centos7 .Net Core 使用Supervisor守护进程,进行后台运行
    Nginx反代理ASP.NET Core项目
    C# vb .net实现圆角矩形特效滤镜
    C# vb .net实现旋转特效滤镜
  • 原文地址:https://www.cnblogs.com/skyfreedom/p/11783629.html
Copyright © 2020-2023  润新知