【问题标题】:How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#?如何调用从 C# 接受字符串流类型参数的 C++ DLL 的函数?
【发布时间】:2010-12-27 12:14:46
【问题描述】:

我想导入一个非托管 C++ DLL 并调用一个以stringstream 作为参数的函数。在 C# 中,没有 stringstream 类,所以谁能告诉我如何从 C# 程序中调用这样的函数?

【问题讨论】:

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


    【解决方案1】:

    您不应该通过 DLL 公开模板化对象,句号。

    模板对象(例如std:: 中的几乎所有内容)都变为内联对象。因此,通过这种方式,您的 DLL 将获得自己的私有实现副本。调用您的 DLL 的模块也将获得自己的 stringstream 私有实现。在它们之间传递意味着您无意中将两个不相关的实现编织在一起。对于许多项目,如果您使用完全相同的构建设置,那可能没问题。

    但即使您使用相同的编译器,并将发布 DLL 与调试 EXE 混合使用,您也会发现堆栈/堆损坏和其他难以发现的问题。

    这只是使用来自另一个非托管 C++ exe/dll 的 DLL。越过 .NET 的界限就更成问题了。

    解决方案是将您的 DLL 接口更改为跨 DLL 边界友好的接口。要么是 COM(例如,你可以使用 IStream),要么只是像 winapi 这样的 C 风格接口。

    【讨论】:

    • 我尝试在非托管 C++ 中导入一个函数,该函数将 std:string 作为参数导入 C# 程序并得到以下运行时错误:“未处理的异常:System.AccessViolationException:试图读取或写入受保护的内存。这通常表明其他内存已损坏。在 Win32API.ProcessRequestWithStream(String& inputString, String& outputString) at Win32API.Main()" - 导致此错误的原因可能是什么?
    • std::stringstd::basic_string<char, std::allocator>typedef,即,它与 stringstream 一样模板化。
    • 那么各种智能指针呢?如果我从字面上理解,这意味着不应跨 DLL 边界公开非平凡的 C++。
    • 重点在于内联代码。有办法导出 C++ 对象没有问题,因为实现有一个家。模板化(或任何内联)实现会获得许多独立的实现,并且不会混合。包括智能指针。但他们指向的对象,不一定。
    • 我很确定 VS 定义 _USER_DLL 会自动导出 basic_string 系列。见support.microsoft.com/kb/168958
    【解决方案2】:

    如果您可以修改 C++ dll,请导出纯字符串版本。否则,您必须构建一个托管 C++ 包装器项目,导入其他 C++ dll,将其导出为托管函数,然后从您的 C# 代码中调用它。 C++ 互操作真的很烂。

    【讨论】:

      【解决方案3】:

      恐怕您必须在 C# 中创建自己的 StringStream 类才能使用从该 DLL 导出的函数。正如您所提到的,.NET Framework 没有提供任何开箱即用的类似类。

      最简单的方法可能是包装 .NET Framework 提供的 StringBuilder 类,使其可以作为流运行。更多解释和一些示例代码请参见this blog post

      MSDN 杂志也回答了类似的问题:http://msdn.microsoft.com/en-us/magazine/cc163768.aspx。您可能会发现那里提供的一些提示和/或示例代码很有用。

      【讨论】:

        【解决方案4】:

        您正在尝试将本机 C++ 代码绑定到 C# 中的托管代码。一般来说,最好的方法是在托管 C++ 中引入中间层,该中间层将为来自 C# 的调用提供接口。

        【讨论】:

          【解决方案5】:

          在 c 或 c++ 中创建一个 Wrapper dll,公开对该函数的友好调用。这是更好的方法。

          例如一个

          BOOL getString(TCHAR * myreturnString, DWORD *size);
          

          【讨论】:

            猜你喜欢
            • 2010-11-16
            • 1970-01-01
            • 2010-10-15
            • 2010-11-25
            • 1970-01-01
            • 2014-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多