【发布时间】:2010-12-27 12:14:46
【问题描述】:
我想导入一个非托管 C++ DLL 并调用一个以stringstream 作为参数的函数。在 C# 中,没有 stringstream 类,所以谁能告诉我如何从 C# 程序中调用这样的函数?
【问题讨论】:
标签: c# c++ visual-c++ dll
我想导入一个非托管 C++ DLL 并调用一个以stringstream 作为参数的函数。在 C# 中,没有 stringstream 类,所以谁能告诉我如何从 C# 程序中调用这样的函数?
【问题讨论】:
标签: c# c++ visual-c++ dll
您不应该通过 DLL 公开模板化对象,句号。
模板对象(例如std:: 中的几乎所有内容)都变为内联对象。因此,通过这种方式,您的 DLL 将获得自己的私有实现副本。调用您的 DLL 的模块也将获得自己的 stringstream 私有实现。在它们之间传递意味着您无意中将两个不相关的实现编织在一起。对于许多项目,如果您使用完全相同的构建设置,那可能没问题。
但即使您使用相同的编译器,并将发布 DLL 与调试 EXE 混合使用,您也会发现堆栈/堆损坏和其他难以发现的问题。
这只是使用来自另一个非托管 C++ exe/dll 的 DLL。越过 .NET 的界限就更成问题了。
解决方案是将您的 DLL 接口更改为跨 DLL 边界友好的接口。要么是 COM(例如,你可以使用 IStream),要么只是像 winapi 这样的 C 风格接口。
【讨论】:
std::string 是 std::basic_string<char, std::allocator> 的 typedef,即,它与 stringstream 一样模板化。
basic_string 系列。见support.microsoft.com/kb/168958。
如果您可以修改 C++ dll,请导出纯字符串版本。否则,您必须构建一个托管 C++ 包装器项目,导入其他 C++ dll,将其导出为托管函数,然后从您的 C# 代码中调用它。 C++ 互操作真的很烂。
【讨论】:
恐怕您必须在 C# 中创建自己的 StringStream 类才能使用从该 DLL 导出的函数。正如您所提到的,.NET Framework 没有提供任何开箱即用的类似类。
最简单的方法可能是包装 .NET Framework 提供的 StringBuilder 类,使其可以作为流运行。更多解释和一些示例代码请参见this blog post。
MSDN 杂志也回答了类似的问题:http://msdn.microsoft.com/en-us/magazine/cc163768.aspx。您可能会发现那里提供的一些提示和/或示例代码很有用。
【讨论】:
您正在尝试将本机 C++ 代码绑定到 C# 中的托管代码。一般来说,最好的方法是在托管 C++ 中引入中间层,该中间层将为来自 C# 的调用提供接口。
【讨论】:
在 c 或 c++ 中创建一个 Wrapper dll,公开对该函数的友好调用。这是更好的方法。
例如一个
BOOL getString(TCHAR * myreturnString, DWORD *size);
【讨论】: