在 C# 中使用带有字符串的 C++ 类 (Dll)
Posted
技术标签:
【中文标题】在 C# 中使用带有字符串的 C++ 类 (Dll)【英文标题】:Use C++ class in C# with strings (Dll) 【发布时间】:2017-10-31 15:07:44 【问题描述】:我正在尝试在我的 C# 程序中使用我的 C++ 类。所以我制作了一个 .dll 文件以在 C# 中使用它。我的问题是,我正在使用字符串。我的问题是:如何将 std::string 返回到我的 C# 程序?
我的 C++ 类(头文件):
using namespace std;
class CComPort
public:
string ReadLine();
void WriteLine(string userInput);
;
我的 dll 代码:
string CppWrapper::CComPortWrapper::ReadLineWrapper()
return comPort->ReadLine();
void CppWrapper::CComPortWrapper::WriteLineWrapper(string userInput)
comPort->WriteLine(userInput);
我的 C#-代码:
comPort.WriteLineWrapper(tb_send.Text);
错误:
'CComPortWrapper.WriteLineWrapper(?,?)' is not supported by the language.
我尝试将 dll 文件更改为类似的内容,但没有成功:
void CppWrapper::CComPortWrapper::WriteLineWrapper(String ^ userInput)
comPort->WriteLine(userInput);
改变它的正确方法是什么?
【问题讨论】:
std::string in C#?的可能重复 std::string 不受 C# 语言支持。我们无法判断您的 ComPort::WriteLine() 函数需要什么类型,但 Marshal::StringToHGlobalAnsi() 往往适合。不要忘记 Marshal::FreeHGlobal()。注意确切的编码也没有什么坏处,考虑将其声明为void WriteLine(array<Byte>^ buffer);
并使用 pin_ptr
以便 C# 代码可以使用 Encoding 类正确处理。
【参考方案1】:
看来您正在包装一个仅用于串行端口通信的类。有一些方法可以直接从 C# 访问串行端口,而无需 C++/CLI。除非 C++ 类中有很多逻辑无法移植/难以移植到 C#,否则请考虑在 C# 中进行串行通信。
你还没有向我们展示你的CComPortWrapper
类的声明。我假设它是public ref class CComPortWrapper
。
如果您的包装器的目标是使其可从托管语言(例如 C#)中调用,那么您应该在声明中使用托管类型。
在这种情况下,您应该声明CComPortWrapper
的方法以获取并返回System::String^
。在包装器中,将其转换为/从std::string
,并用它调用非托管类。
我建议使用marshal_as
进行转换,尤其是因为您要从一个类转换到另一个类。您不需要处理显式分配内存或类似的事情;让每个字符串类管理自己的内存,让marshal_as
处理数据的复制和转换。
#include <msclr\marshal_cppstd.h>
using namespace System;
String^ CppWrapper::CComPortWrapper::ReadLineWrapper()
std::string result = comPort->ReadLine();
return marshal_as<String^>(result);
void CppWrapper::CComPortWrapper::WriteLineWrapper(String^ userInput)
std::string input = marshal_as<std::string>(userInput);
comPort->WriteLine(input);
【讨论】:
您的代码出现此错误:“'msclr::interop::error_reporting_helper<_to_type>::marshal_as': 库或头文件不支持此转换不包括此转换所需的内容。请参阅有关“如何:扩展编组库”的文档以添加您自己的编组方法。” 是的,它是'public ref class CComPortWrapper' @User987123 确保您有正确的包含。见编辑。以上是关于在 C# 中使用带有字符串的 C++ 类 (Dll)的主要内容,如果未能解决你的问题,请参考以下文章
调用从 c# 返回 char* 的 c++ dll 函数。无法使用 DllImport()
将带有参数的 c# 回调方法传递给 c++ dll 会导致 System.ExecutionEngineException