从本机调用 C# 以检索字符串

Posted

技术标签:

【中文标题】从本机调用 C# 以检索字符串【英文标题】:Call C# from native to retrieve a String 【发布时间】:2015-12-30 15:05:33 【问题描述】:

我整天都被困在这个问题上,但似乎不可能,至少使用 compact 框架,从本机代码调用 返回的 C# 方法 一个字符串。

我见过几个关于在本机代码之间传递数据的示例,但没有一个示例使用返回值。

我想做的是有一个 C# 函数,它返回一个字符串,这样我就可以将它从 C# 拉回到 C++,即从 C++ 调用 C#,而不是其他方式。

String GetSomeString()  return "foo";  // C#

并从具有如下签名的本机代码调用此函数:

typedef const wchar_t * (__stdcall * native_func_t)();

问题在于它不起作用。当我将委托传递给本机代码时,会引发 NotSupportedException。但是,如果我用 void 替换 String 返回类型,它就可以完美地工作。

其他解决方案是:

从 C++ 调用 C# 以获取字符串长度,在 C++ 上分配该字符串,将其传递给 C# 并使用不安全代码填充缓冲区。但这又脏又不实用,所以我不会那样做。

使 C# 函数调用一个 C++,该 C++ 将结果存储在某处,并且在本机代码中,在对 C# 的调用返回后检索该结果的存储位置。但这也很丑陋,不实用。

请问您还有其他方法吗?

【问题讨论】:

C++ 二进制文件如何加载 C# 程序集?这是来自回调并且进程本身是托管代码吗? 我会使用 COM BSTR。也就是说,在 C++ 端进行分配是一个不错的选择。如果没有对这个主题有更深入的了解,你不应该说这不好。 @ctake 实际上它是一个 Windows 窗体应用程序。 C# 处理 GUI,但所有其余工作都由本机代码完成。 您还没有解释调用 C++ 代码的机制,以及从 C++ 代码调用 C# 代码的机制。这些是互操作问题中的关键细节。 【参考方案1】:

*** 和其他方面已经提出了这个问题。

一个 *** 帖子位于 Calling a C# function from a C++ DLL。

链接的解决方案使用 CF 中提供的 CallingConvention.StdCall,但您可以使用 CallingConvention.WinApi 代替,根据此站点转换为 CallingConvention.StdCall https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.callingconvention%28v=vs.90%29.aspx

您还可以在窗口和表单句柄之间使用其他互操作技术,例如自定义消息 (SendMessage)。

要向 C++ 公开托管组件,请使用 COM(请参阅 https://msdn.microsoft.com/en-us/library/zsfww439%28v=vs.80%29.aspx)

【讨论】:

【参考方案2】:

实际上,当从 C++ 调用时,似乎没有 C# 函数可以返回一些东西。 任何除 void 以外的返回类型都会导致抛出 NotSupportedException。

我在 MSDN 文档中没有找到这方面的证据,但经过大量测试后,它似乎是这样工作的,至少对于 compact framework

【讨论】:

以上是关于从本机调用 C# 以检索字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在托管代码(C#)中从本机代码(C++)获取字符串数组

从 C++ 传递函数指针以由 C# 调用 - 函数参数包括宽字符字符串 (LPCWSTR)

c# - 如何从忽略字符串空格的列表中检索字符串元素?

C# ConfigurationManager 从 app.config 检索错误的连接字符串

*** 关于从 C# 调用本机 C++

使用 C# 从 sqlite 3 数据库中检索存储在整数字段中的字符串数据