从C ++ / CLI调用C#函数-将返回C#字符串转换为C字符串 [英] Calling C# function from C++/CLI - Convert Return C# string to C String

查看:79
本文介绍了从C ++ / CLI调用C#函数-将返回C#字符串转换为C字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个制作成DLL的C#函数:

I have a C# function that I made into a DLL:

public static string Test(string name)
{
    return "Hello " + name;
}

在C ++ / CLI项目中,我成功导入了该DLL,现在我想拥有一种调用该函数并使之可用于普通非托管C ++的方法。所以我想像这样导出C ++ / CLI函数:

In C++/CLI project I successfully import that DLL, now I want to have a way to call that function and make it available for normal unmanaged C++. So I want to export the C++/CLI function like this:

extern "C" __declspec(dllexport)
void __stdcall Example(char* name, char* greet) {
    // name will be passed to C# Test(...) function
    // and greet will contains the returned value

    // call to the C# function here:
    ...
}

我不在乎C ++ / CLI函数是什么样的,只要我可以将其导出到普通的非托管C ++中即可。

I dont care what the C++/CLI function looks like, as long as i can export it to normal unmanaged C++.

**编辑:有人抱怨我问题,我只需要知道在给定C字符串的情况下如何调用C#函数,以及如何检索返回的结果并将其存储在另一个C字符串中。这不像一个问题,就像一个不知道如何编码的新手,来这里问...谢谢**

** as someone complain about my question, I only need to know how you can call the C# function, given a C string, and how to retrieve the returned result and store it in another C string. It's not like a "problem", it's like a newbie who don't know how to code, and come here to ask... Thank you **

** Edit2:现在我注意到,有人编辑了我的帖子(我不知道,主持人还是某人...)。现在,当我重新阅读我的帖子时,即使我也不知道该帖子要问什么...请,我认为您不应该这样做**

** now i noticed, someone has edited my post (i dont know, a moderator or someone...). Now when i re-read my post, even i don't know what the post trying to ask... Please, i think you shouldn't do that **

推荐答案

使用C ++ / CLI,您可以随时使用所需的一切。

With C++/CLI you have everything you need at your disposal.

您可以这样操作:

#include <string>
#include <msclr\marshal_cppstd.h>

extern "C" __declspec(dllexport)
void __stdcall Example(char* name, char* greet) {
    // name will be passed to C# Test(...) function
    // and greet will contains the returned value

    // Create new System::String^ from char*
    System::String^ clrString = msclr::interop::marshal_as<System::String^>(name);

    // Call C# function
    System::String^ result = Test(clrString);

    // Create new std::string from System::String^
    std::string cppString = msclr::interop::marshal_as<std::string>(result);

    // Copy C++-string to the destination
    strcpy(greet, cppString.c_str());
}

此解决方案使用 std :: string 。您还可以使用 marshal_context 直接在 System :: String char []之间进行转换。 ,但我更喜欢使用 std :: string ,因为它可以节省一些键入时间,而且出错的地方更少。

This solution uses std::string. You can also use a marshal_context to directly convert between System::String and char[], but I prefer to use std::string since it saves you some typing and there is less to go wrong.

当然,可以将其缩短为:

Of course, one can shorten this down to:

strcpy(greet, marshal_as<string>(Test(marshal_as<String^>(name))).c_str());

甚至更远,因为 System :: String 有一个接受 char * 的构造函数:

Or even further, since System::String has a constructor accepting char*:

strcpy(greet, marshal_as<string>(Test(name)).c_str());

在这里查看有关编组的更多信息: http://msdn.microsoft.com/en-us/library/bb384865.aspx

Have a look here for more info about marshalling: http://msdn.microsoft.com/en-us/library/bb384865.aspx

重要提示:
C#使用动态字符串,而C#代码通常会很高兴地生成很长的字符串,如果<$ c指向的内存导致崩溃或更糟$ c> greet 的大小不足以容纳字符串。
一种常见的处理方法是将 Example 的签名更改为以下内容:

Important: C# uses dynamic strings and C# code often happily generates very long strings, resulting in a crash or worse if the memory pointed to by greet is not large enough to contain the string. A common way to deal with this is to change the signature of Example to something like this:

void __stdcall Example(char* name, char* greet, size_t destBufferSize)

然后检查destBufferSize是否足够大以包含结果字符串或使用 strncpy 或类似方法截断值。

And check if the destBufferSize is large enough to contain the resulting string or truncate the value using strncpy or similar methods.

这篇关于从C ++ / CLI调用C#函数-将返回C#字符串转换为C字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆