2014-11-02 85 views
0

我为C++库创建了一个C包装,我从C#托管代码中调用了这个C包装。我面临的问题是这个库涉及数千次迭代和长时间运行。很明显,我需要一种与C#程序进行通信的方式,并更新C/C++库正在处理的状态。使用P/Invoke在托管代码和非托管代码之间共享内存

直接方法将在固定次数的迭代后返回,更新状态并再次调用C/C++包装器。但是处理依赖于一些基于C++ STL的数据结构,这些数据结构在每次迭代后都会更新。我不需要托管代码上的这些数据结构,但显然它们必须在所有迭代中保留在内存中。

所以我不能从C返回/ C++包装,直至处理完毕,否则C++结构将被释放......

我想将共享托管和非托管代码之间的一些变量的最佳方法,并每N次迭代读取处理状态。但是这会导致另一个问题:我如何同步对这个内存的访问?

+0

为什么数据结构在包装返回时会被解除分配? – Blorgbeard 2014-11-02 22:34:36

+0

因为它们是由被调用函数分配的。使用全局变量或未释放的动态内存似乎是一个肮脏而不稳定的解决方案我可以确定这个动态内存或全局变量在调用封装后不会被清除吗?如果DLL被卸载会怎么样? – sapito 2014-11-02 22:45:08

回答

1

您可以在您的C++代码中将C#委托注册为回调。这样你不必从包装器返回,但是你的包装器可以通过回调调用C#委托,然后可以继续处理。您的代理还可以包含一些参数,您可以使用它们在C#和C++图层之间交换数据。

查看更多的完整描述here

这里的主要技巧是使用方法GetFunctionPointerForDelegate,它允许您从C#委托中创建C++函数指针,以便您可以从C++层调用C#代码。

+0

它不需要一个技巧,pinvoke编组人员已经使用GFPFD编组委托。 – 2014-11-02 22:43:52

+0

谢谢。由于我是P/Invoke的初学者,我不知道这个特性。这似乎是实施状态更新的最佳方法。 – sapito 2014-11-02 22:49:25

+0

@Hans Passant。谢谢,很高兴知道,上次我仅在C++/CLI包装中使用它。 – pgenfer 2014-11-02 22:50:12