从托管或生成进程调用非托管代码

时间:2009-05-19 20:12:56

标签: c# .net c++ unmanaged

我有一个非托管的C ++ exe,我可以从我的C#代码中直接调用(拥有我可以创建lib的C ++代码),或者通过生成一个进程并从OutputStream中获取数据。这些选项有哪些优点/缺点?

5 个答案:

答案 0 :(得分:1)

由于您拥有C ++库的源代码,因此可以使用C ++ / CLI将其编译为混合模式dll,以便C#应用程序可以轻松使用它。

这样做的好处是对数据流(输入或输出到该C ++模块)最灵活。

在进程外运行C ++代码有一个好处。如果您的C ++代码不是很健壮,这可以使您的主C#进程稳定,以免被C ++代码崩溃。

答案 1 :(得分:0)

刮掉OutputStream的一大缺点是缺少数据输入。我宁愿做导出一些功能和重用现有库的工作;但是,这真的只是一种偏好。

答案 2 :(得分:0)

产生一个过程的另一个缺点是,在窗口上吐出一个过程是一个非常昂贵(缓慢)的操作。如果您打算经常调用c ++代码,这值得考虑。 一个优点是你可以自动更加孤立于c ++程序中的崩溃。 放弃替换c ++可执行文件也是一个优点。 此外,在c#中编写互操作代码可能会很麻烦。如果它是一个复杂的interace并且您决定进行互操作,请查看interop层的c ++ / cli。

答案 3 :(得分:0)

最好不要使用C ++可执行文件的一部分函数并将其构建到库中。您将保持类型安全,并且您将能够更好地利用异常处理(更不用说如何管理对库中函数的调用的更细粒度控制)。

如果您从可执行文件的OutputStream中获取数据,您将无法查看可执行文件的进程,没有真正的异常处理,并且您将丢失任何类型信息。了。

答案 4 :(得分:0)

正在进行的主要缺点是确保正确处理托管/本机交互。

1)

c ++代码可能依赖于清除/资源释放的确定性破坏等等。我说可能是因为这是c ++中的常见和良好实践。

在托管代码中,这意味着您必须小心处理正确的c ++ cli包装器代码。如果您的代码使用一次,c#中的using子句将为您执行此操作。如果对象需要作为成员存活一段时间,您会发现需要在应用程序的整个过程中对该处置进行链接。

2)

另一个问题取决于您的应用程序的内存耗尽程度。托管垃圾收集器可能很懒惰。如果托管分配需要的空间超出可用空间,则可以保证启动。但是,无管理的分配器无论如何都没有连接。因此,您需要通过manaully通知托管分配器您将进行非托管分配,并且应该保持该空间可用。这是使用AddMemoryPressure方法完成的。

退出流程的主要缺点是:

1)速度。

2)管理通信的代码开销。

3)在不期望的情况下监视一个或其他进程死的代码开销。