在C#中使用带有字符串的C ++类(Dll)

时间:2017-10-31 15:07:45

标签: c# c++ dll c++-cli

我正在尝试在C#程序中使用我的C ++类。所以我创建了一个.dll文件来在C#中使用它。我的问题是,我正在使用字符串。我的问题是:如何将std :: string返回给我的C#程序?

我的C ++类(header-file):

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);
}

改变它的有效方法是什么?

1 个答案:

答案 0 :(得分: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);
}