从本机调用 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# 调用 - 函数参数包括宽字符字符串 (LPCWSTR)