C++/CLI打通C++与C#

导读:本篇文章讲解 C++/CLI打通C++与C#,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

使用 C++/CLI 进行 .NET 编程 | Microsoft Docsicon-default.png?t=M4ADhttps://docs.microsoft.com/zh-cn/cpp/dotnet/dotnet-programming-with-cpp-cli-visual-cpp?view=msvc-170C++/CLI 是C++编程语言的变体,针对公共语言基础结构进行了修改。它一直是Visual Studio 2005及更高版本的一部分,并提供与其他.NET语言(如C#)的互操作性。Microsoft 创建了 C++/CLI 来取代 C++ 托管扩展

简单来说,C++/CLI是C++和C#这两个世界的桥接。

它可以让C#(或者其它.net语言)访问纯C++,反之还可以让C++访问C#的dll;

通常没有人使用C++/CLI作为主要语言。这不是它的设计目的。虽然 C# 是一种高效的语言,在性能方面并不逊色,但实际上有很多原因,我们还是得以纯C++编写项目的一部分。

C++/CLI 在许多方面都是独一无二的,使用它的软件项目往往是内部代码库的项目,无法在组织外部共享。

C#调用c++的例子太多了,以下简单演示C++使用C#的dll:

以下为C#写的MyCs.dll

namespace MyCS;

public class Class1 {
    public static double add(double a, double b) {
        return a + b;
    }
}

以下为C++调用:

#include "stdafx.h"
using namespace System;
#using "...MyCS.dll"

int main(array<System::String ^> ^args) {
    double x = MyCS::Class1::add(40.1, 1.9);
    return 0;
}

就如此简单,C++/CLI让两个语言打通了。

当然以下只是演示功能,实际使用过程中,不可避免涉及到数据“封送处理”,以下演示,将字符串从C++字符串封送到可从 C# 调用的字符串,然后再封送到C++字符串。

#include <string>
#include <iostream>
#include <msclr\marshal_cppstd.h>
#include "stdafx.h"
using namespace System;
#using "..MyCS.dll"

int main() {
	std::string s = "I am cat";
	System::String^ clrString = msclr::interop::marshal_as<System::String^>(s); // string usable from C#
	System::String^ t = MyCS::Class1::process(clrString); // call C# function
	std::string cppString = msclr::interop::marshal_as<std::string>(t); // string usable from C++
	std::cout << "Hello, C++/C# Interop!" << std::endl;
	std::cout << cppString << std::endl;
	return 0;
}

其他类型,就得参考微软文档:

如何:使用 C++ 互操作封送 ANSI 字符串 | Microsoft Docsicon-default.png?t=M4ADhttps://docs.microsoft.com/zh-cn/cpp/dotnet/how-to-marshal-ansi-strings-using-cpp-interop?view=msvc-170

以下演示返回值为char*

C#部分 ReverseText.dll

public static string ReverseText(this string str)  // 翻转字符串
{
    StringBuilder sb = new StringBuilder();
    for (int i = str.Length - 1; i > -1; i--)
    {
        sb.Append(str[i].ToString());
    }
    return (sb.ToString());
 }

 C++/CLI桥梁部分

static char* p_result;
_declspec(dllexport) bool free_h_global(void)
{
	if(p_result!=NULL)
	{
		Marshal::FreeHGlobal(IntPtr((void*)p_result));
		p_result=NULL;
		return true;
	}
	return false;
}
 _declspec(dllexport) const char * ReverseText(const char * src)
{ 
   const char * p_rv=NULL;
   String^ str = gcnew String("123456");
   String^ out =ReverseText(str);//C#的类用于翻转字符串
   IntPtr ip = Marshal::StringToHGlobalAnsi(out);
   p_rv = (const char*)(static_cast<const char*>(ip.ToPointer());
   Marshal::FreeHGlobal( ip );
   free_h_global();
   p_result=(char *)p_rv;
   return p_rv;
)

C++调用部分

//引入lib及函数
#pragma comment(lib,"ReverseText.lib")
_declspec(dllimport)  const char * ReverseText(const char * src)


//正常调用
string dst=ReverseText("china");

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/96444.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!