C++/CLI 包装引用 Native C++ 简单测试
托管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);
        Marshal::FreeHGlobal((IntPtr)c_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# 项目引用
不能用 .c 后缀编译的 dll,给 .cpp 后缀的项目使用。要相同种类的编译。
 
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号