在您的 C# 代码中,使用 DLLImport 属性声明您的本机 C++ 方法,并从您的BackgroundWorker.ProgressChanged
处理程序中调用此方法。
免责声明:我没有测试过任何这段代码,这可能不是最好的方法,但至少在理论上我认为这是可行的。希望这里更有经验的成员之一可以验证这是否真的正确。
这假设您正在从 C# 启动后台工作程序,并且您想要ProgressChanged
C# 中的事件(我假设是这种情况,因为您的 UI 在 C# 中)。
您仍然可以BackgroundWorker
在 C# 中使用,但只需使用我上面提到的 DLLImport 调用您的本机方法。您还可以修改方法的签名以获取与签名匹配的函数指针,ReportProgress
然后从您的本机代码调用该委托。
MSDN 有一些关于编组委托和函数指针的文章(尽管示例都使用 C++/CLI)。您可能还想查看DLLImport和MarshalAs属性以及UnmanagedType枚举的文档。
例如,如果您的本机方法是
void foo(int arg1, BOOL arg2)
{
// Your code here
}
您将在本机代码中定义函数指针类型为
// Corresponds to void BackgroundWorker.ReportProgress(int progress, object state)
typedef void (*NativeReportProgress) (int, void*);
并将您的本机签名更改为
void foo(int arg1, BOOL arg2, NativeReportProgress progressPtr)
{
// Some code.
progressPtr(progressValue, stateVar);
}
你DLLImport
的 forfoo
看起来像
// Delegate type for BackgroundWorker.ReportProgress
delegate void ReportProgressDelegate(int progress, object state);
// The MarshalAs attribute should handle the conversion from the .NET
// delegate to a native C/C++ function pointer.
[DLLImport]
void foo([MarshalAs(UnmanagedType.I4)] Int32 arg1,
[MarshalAs(UnmanagedType.Bool)] bool arg2,
[MarshalAs(UnmanagedType.FunctionPointer)] ReportProgressDelegate progressDel);
然后你的工人看起来像
void DoWork(object sender, DoWorkEventArgs e)
{
var worker = (BackgroundWorker)sender;
// Notice that worker.ReportProgress is not followed the by ().
// We're not actually calling the method here, we're just passing
// a function pointer to that method into foo.
foo(intArg, boolArg, worker.ReportProgress);
}
希望这是有道理的(希望它也是正确的!)