首页 > 编程语言 >C++/CLI 包装引用 Native C++ 简单测试

C++/CLI 包装引用 Native C++ 简单测试

时间:2023-12-07 13:46:02浏览次数:43  
标签:include Animals name int void C++ using Native CLI

托管C++

这个项目名:CppCLI

Animals.h

#pragma once
using namespace System;

namespace Zoological
{
    public ref class Animals
    {
    public:
        int GetLegs();
        void SetLegs(int legs);
        String^ GetName();
        void SetName(String^ name);
    private:
        int m_Legs;
        String^ m_Name;
    };
}

Animals.cpp

#include "pch.h"
#include "Animals.h"
namespace Zoological
{
    int Animals::GetLegs()
    {
        return m_Legs;
    }

    void Animals::SetLegs(int legs)
    {
        m_Legs = legs;
    }

    String^ Animals::GetName()
    {
        return m_Name;
    }

    void Animals::SetName(String^ name)
    {
        m_Name = name;
    }
}

主函数:

#include "pch.h"
#include "Animals.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    using namespace Zoological;    // 命名空间
    Animals^ animal = gcnew Animals();

    animal->SetLegs(4);
    animal->SetName("小狗");
    
    Console::WriteLine("{0}有 {1} 条腿", animal->GetName(), animal->GetLegs());
    return 0;
}

输出:

小狗有 4 条腿



C# 直接调用

将上面的托管 C++ 生成 Dll, 新建一个 C# 程序, 引用 dll 可以直接调用:

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

using Zoological;  // 引用命名空间

namespace ConsoleApp19_CSCPPCLI
{
    class Program
    {
        static void Main(string[] args)
        {
            Animals animals = new Animals();
            animals.SetName("小狗");
            animals.SetLegs(4);
            Console.WriteLine($"{animals.GetName()}有 {animals.GetLegs()} 条腿。");
            Console.ReadKey();
        }
    }
}

输出:

小狗有 4 条腿。




C++/CLI 托管 C++ 包装 Native C++

Native C++

新增 NativeCpp 项目:

Animals.h

#pragma once

#include <string>
#define DllExport   __declspec(dllexport)

namespace ZoologicalNative
{
    class DllExport Animals
    {
    public:
        int GetLegs();
        void SetLegs(int legs);
        std::string GetName();
        void SetName(std::string name);
    private:
        int m_Legs;
        std::string m_Name;
    };
}

Animals.cpp

#include "Animals.h"

namespace ZoologicalNative
{
    int Animals::GetLegs()
    {
        return m_Legs;
    }

    void Animals::SetLegs(int legs)
    {
        m_Legs = legs;
    }

    std::string Animals::GetName()
    {
        return m_Name;
    }

    void Animals::SetName(std::string name)
    {
        m_Name = name;
    }
}

托管 C++/CLI 中包装

这个项目名:CppCLI

Animals.h

#pragma once
#include "../NativeCpp/Animals.h"
using namespace System;

namespace Zoological
{
    public ref class Animals
    {
    public:
        Animals();
        ~Animals();
        int GetLegs();
        void SetLegs(int legs);
        String^ GetName();
        void SetName(String^ name);
    private:
        ZoologicalNative::Animals* m_pImpl;
    };
}

Animals.cpp

#include "pch.h"
#include "Animals.h"
#include <string>
//#include <msclr\marshal.h>
//#include "msclr/marshal_windows.h"
//#include "msclr/marshal_cppstd.h"
//#include "msclr/marshal_atl.h"

#pragma comment(lib, "../Debug/NativeCpp.lib")

namespace Zoological
{
    Animals::Animals()
    {
        m_pImpl = new  ZoologicalNative::Animals();
    }

    Animals::~Animals()
    {
        delete m_pImpl;
    }

    int Animals::GetLegs()
    {
        return  m_pImpl->GetLegs();
    }

    void Animals::SetLegs(int legs)
    {
        m_pImpl->SetLegs(legs);
    }

    String^ Animals::GetName()
    {
        //return msclr::interop::marshal_as<String^>(m_Animals->GetName());  // 这个不行 指针不允许指向 ref class

        std::string name = m_pImpl->GetName();
        const char* c_name = name.c_str();
        String^ cli_name = gcnew String(c_name);

        return cli_name;
    }

    void Animals::SetName(String^ name)
    {
        // 这个不行 指针不允许指向 ref class
        /*  std::string name_std = msclr::interop::marshal_as<std::string>(name);
          m_Animals->SetName(name_std);*/

        using namespace System::Runtime::InteropServices;
        char* c_name = (char*)(void*)Marshal::StringToHGlobalAnsi(name);
        std::string s_name = std::string(c_name);
        m_pImpl->SetName(s_name);
    }
}

主函数:

#include "pch.h"
#include "Animals.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    using namespace Zoological;
    Animals^ animal = gcnew Animals();

    animal->SetLegs(4);
    animal->SetName("哮天犬");
    
    Console::WriteLine("{0} 有 {1} 条腿", animal->GetName(), animal->GetLegs());
    return 0;
}

输出:

哮天犬 有 4 条腿

托管 C++ 导出 DLL 给到 C# 调用

这个引用好CppCLI.dll,直接调用没什么特别的。

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

using Zoological;

namespace ConsoleApp19_CSCPPCLI
{
    class Program
    {
        static void Main(string[] args)
        {
            Animals animals = new Animals();
            animals.SetName("牛魔王");
            animals.SetLegs(4);
            Console.WriteLine($"{animals.GetName()}有 {animals.GetLegs()} 条腿。");
            Console.ReadKey();
        }
    }
}

输出:

牛魔王有 4 条腿。

▲ C# 项目引用

标签:include,Animals,name,int,void,C++,using,Native,CLI
From: https://www.cnblogs.com/huvjie/p/17881116.html

相关文章

  • Maven无法下载fastdfs-client-java依赖问题解决
    一、分析原因控制台报错具体如下:并且pom.xml中以下依赖爆红:<dependency><groupId>org.csource</groupId><artifactId>fastdfs-client-java</artifactId><version>1.29-SNAPSHOT</version></dependency>原因:因为fastdfs-clien......
  • 云课五分钟-05一段代码修改-AI修改C++
    前篇:云课五分钟-04一段代码学习-大模型分析C++在前一节,使用大模型工具文心一言等可以帮助分析代码,加快理解。信息时代→智能时代,系统学习转为碎片学习。发散思维的能力在智能时代尤为重要。 同样我们也可以借助智能化工具修改代码,提出自己的需求。所有的云课五分钟,不仅演示可行案......
  • Native Drawing开发指导,实现HarmonyOS基本图形和字体的绘制
     场景介绍Native Drawing模块提供了一系列的接口用于基本图形和字体的绘制。常见的应用场景举例:● 2D图形绘制。● 文本绘制。接口说明接口名描述OH_Drawing_BitmapCreate (void)创建一个位图对象。OH_Drawing_BitmapBuild (OH_Drawing_Bitmap......
  • 阅读《Effective c++》第三版 day 3
    ·考虑提供更搞效且安全的swap函数:对于一般缺省的swap函数,可能引发拷贝构造函数,导致性能下降,swap应设计为提供异常安全性保障而不抛出异常,但缺省版本的swap时可能抛出的,所以重新设计swap是应该的。此前设计operator=函数也有稍微提过。此外考虑类的设计模式,也会有低效率的swap......
  • C++中的函数重载(C++Primer)
    一、什么是函数的重载在同一作用域下,几个函数的函数名相同,但其内部的形参列表不同,我们称之为函数的重载,这里的不同不仅仅指形参数量的不同,还包括形参类型的不同。voidprint(constchar*const_p);voidprint(constchar*begin,constchar*end);voidprint(constint*const_p)......
  • C++实现LL1语法分析器
    C++实现LL1语法分析器:预备知识:​ LL1分析法是一种确定的自上而下的分析方法,通过在输入中向前看固定个数(通常为1)的符号来选择正确的产生式从而实现预测分析的效果,预测分析不需要回溯。​由以上定义,LL1分析器是一种表驱动的语法分析器,分析器依赖于语法分析表,需要在输入......
  • C++_调用函数以及不同数据类型
    调用其他文件中的函数add_library可以生成我们所需的动态库或者静态库,我们要把制作出的库文件发布出去供第三方使用一些函数方法单独在一个cpp的源文件中定义,然后在另一个源文件中需要用到自定义的函数时直接调用就可以了!方法1.学过c++的人可能最熟悉的方法还是利用头文件......
  • C++中的const用法
    一、修饰普通变量:constdoublePI=3.14159;constinta=10;//这些C++中的内置类型被const修饰时,其值不可被随意更改二、修饰一个指针(即指针对应的值不可修改):但是指针作为一个变量,其可指向其他位置,只是无法通过指针来改变其指向的对象的值inta=10;intb=20;constint*p......
  • 【解决方案】adb server version (41) doesn't match this client (36);
    【GiraKoo】adbserverversion(41)doesn'tmatchthisclient(36);环境夜神模拟器无法与AndroidStudio连接。使用命令行连接时会提示adbserverversion(41)doesn'tmatchthisclient(36)。通过adbversion命令,可以查看adb的版本。夜神的nox_adb.exe是36版本的,所以导......
  • Qt/C++视频监控拉流显示/各种rtsp/rtmp/http视频流/摄像头采集/视频监控回放/录像存储
    一、前言本视频播放组件陆陆续续写了6年多,一直在持续更新迭代,视频监控行业客户端软件开发首要需求就是拉流显示,比如给定一个rtsp视频流地址,你需要在软件上显示实时画面,其次就是录像保存,再次就是一些周边的处理比如贴OSD,做图片分析等。拉流显示是第一步,如果有跨平台的需求,个人推荐......