[英]operate with loop in unmanaged c++ dll from c#(callbacks)
我已经编写了一个运行良好的非托管c ++ dll(IPinvoke)))其中有一个资源消耗函数-存在一个循环,其中包含复杂的耗时逻辑。 计算此循环进度百分比并向该循环发送中断的最佳方法是什么-使用回调或可能传递参数? 如果回调是最好的变体-有人可以提供示例吗?
在dll中:
extern "C" _declspec(dllexport) uint8* resourceConsumingFunction(uint8* dataBufer)
{
//there is a loop with many math here
return dataBuffer;
}
在C#中
[DllImport("MyLib.DLL", CallingConvention = CallingConvention.Cdecl)]
public unsafe static extern byte* resourceConsumingFunction(byte* dataBuf);
//.....
byte* bufbuf = resourceConsumingFunction(data);//there I need to break this function and to get //percentage
当然,回调可以工作。 您将在C ++代码中需要一个函数指针,如下所示:
typedef void (__stdcall * pfnCallback)(int progress, int* cancel);
extern "C" _declspec(dllexport)
uint8* resourceConsumingFunction(uint8* dataBuffer, pfnCallback callback)
{
for (int progress = 0;;) {
int cancel = 0;
callback(progress, &cancel);
if (cancel) return null;
// More code
//...
}
return dataBuffer;
}
等效的C#代码为:
private void delegate pfnCallback(int progress, out bool cancel);
private void makeCall() {
var callback = new pfnCallback(showProgress);
var bufptr = resourceConsumingFunction(somebuf, callback);
GC.KeepAlive(callback);
// etc...
}
private void showProgress(int progress, out bool cancel) {
// etc...
}
对回调使用__stdcall有助于简化委托声明。 必须使用GC.KeepAlive()来阻止垃圾回收器过早地收集委托对象。
根据您提供的信息,我认为您必须从头开始重写dll。
我将其设置为BackgroundWorker,如下所示(伪代码,在MSDN上查找):
BackgroundWorker worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.DoWork += (s,e) =>
{
loop(loopcondition)
{
... math magic, in which you also calculate percentage ...
worker.ReportProgress(percentage); // fire 'ProgressChanged' event handled below
}
};
worker.ProgressChanged += (s,e) => { /*e.ProgressPercentage is the value you passed, here you handle it*/ };
//WARNING: i don't remember the exact event name right now, look it up!
worker.WorkerCompleted += (s,e) => { /*when job is done, you can do something here*/ };
您可以在ProgressChanged
和WorkerCompleted
事件中与UI进行交互,而不是在DoWork
进行交互(它在单独的线程中运行)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.