2012-10-29 21 views
2

我有一个非常大的函数在我的C++ DLL中执行很多任务。我们从c#wrapper调用它,并且需要大约20秒才能完成C++函数。 我想改变我们运行它的方式。 我的想法是 1.调用C++函数async和 2.每次完成一个带有C++函数的任务时,我想发送“task1 completed”消息给C#函数并显示给用户,以便他们知道后台发生了什么。从C++中的函数发送状态更新到C#

任何想法如何执行此?我查了几个例子,但感到困惑。我想知道是否有人这样做。寻找一些指针。

EX:C++代码

int CppLibrary::ExecuteWorkflow(param1,param2, param3,param4,param5) 
{ 
task1; 
task2; 
task3; 
task4; 
task5; 

} 

calling the C++ function from C# wrapper: 

[DllImport(_dllLocation)] 
public static extern int ExecuteWorkflow(param1,param2, param3,param4,param5); 

回答

0

您可以使用委托在C#中打电话给你的C++包装,然后使用 “援引” 或 “BeginInvoke的” 根据您的情况。

Dispatcher.BeginInvoke Method

+0

谢谢,但你能详细说明一下吗?你建议我在我的c#wrapper中使用委托。但我在哪里使用invoke或begininvoke?我想从我的C++函数发送状态消息到c#wrapper。那么我如何从C++发送它,以及如何捕获C#中的消息?请理解我之前从未使用C++或事件代表。谢谢。 – user1612555

0
  1. 出口(出口 “C” __declspec(dllexport)的)你的C++函数使用C类名
  2. 使用的DllImport您的库调用创建的DllImport。
  3. 创建一个线程并用您的回调逻辑调用导入(即Task.Run with delegate)。
+0

我认为你已经倒退了。 –

+0

嗨。我正在做你建议的前两步。你能否详细说明第三步?我知道如何在c#中使用线程。但我想显示从C++发送的状态消息。我该怎么做?谢谢。 – user1612555

0

这是P/Invoke C++函数的包装类。希望可以帮助你。

class CSUnmangedTestClass : IDisposable 
{ 
    #region P/Invokes 

    [DllImport(@"E:\VS2012Tests\test\Debug\DllImport.dll", EntryPoint="#1")] 
    private static extern IntPtr Foo_Create(); 

    [DllImport(@"E:\VS2012Tests\test\Debug\DllImport.dll", CallingConvention = CallingConvention.Cdecl)] 
    private static extern int Foo_Bar(IntPtr pFoo); 

    [DllImport(@"E:\VS2012Tests\test\Debug\DllImport.dll", CallingConvention = CallingConvention.Cdecl)] 
    private static extern void Foo_Delete(IntPtr pFoo); 

    #endregion 

    #region Members 
    // variable to hold the C++ class's this pointer 
    private IntPtr m_pNativeObject; 
    #endregion 

    public CSUnmangedTestClass() 
    { 
     this.m_pNativeObject = Foo_Create(); 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 

    protected virtual void Dispose(bool bDisposing) 
    { 
     if (this.m_pNativeObject != IntPtr.Zero) 
     { 
      Foo_Delete(m_pNativeObject); 
      this.m_pNativeObject = IntPtr.Zero; 
     } 
     if (bDisposing) 
     { 
      // No need to call the finalizer since we've now cleaned up the unmanged memory 
      GC.SuppressFinalize(this); 
     } 
    } 

    ~CSUnmangedTestClass() 
    { 
     Dispose(false); 
    } 

    #region Wrapper methods 

    public int Bar() 
    { 
     return Foo_Bar(m_pNativeObject); 
    } 

    #endregion 
}