2013-05-07 74 views
0

我想讓C++函數調用C#中的窗體上的方法來更新GUI。出於某種原因,來自C++的函數調用以相反的順序發送參數。從C++通過委託調用C#方法返回參數的結果

因此UpdateDROCallback()函數在函數(1.0,2.0,3.0)中調用時,第一個參數爲3.0,第二個爲2.0,最後一個爲1.0。

我在這裏錯過了什麼?

[C#]

public partial class Form1 : Form 
    { 
     delegate void DROUpdateDelegate(double x, double y, double z); 
     DROUpdateDelegate m_DROUpdateDelegate; 
     static DROUpdateDelegate s_DROUpdateDelegate; 

     public Form1() 
     { 
      InitializeComponent(); 
      m_DROUpdateDelegate = new DROUpdateDelegate(UpdateDROCallback); 
      s_DROUpdateDelegate = new DROUpdateDelegate(UpdateDRO); 
     } 

     private void btnGo_Click(object sender, EventArgs e) 
     { 
      int address = m_DROUpdateDelegate.Method.MethodHandle.GetFunctionPointer().ToInt32(); 
      TestDll.RegisterScaleUpdateCallback(address); 
     } 

     private static void UpdateDROCallback(double x, double y, double z) 
     { 
      s_DROUpdateDelegate(x, y, z); 
     } 

     private void UpdateDRO(double x, double y, double z) 
     { 
      BeginInvoke(
       new Action(
        () => 
        { 
         lblDROX.Text = x.ToString("0.0000"); 
         lblDROY.Text = y.ToString("0.0000"); 
         lblDROZ.Text = z.ToString("0.0000"); 
        })); 
     } 
    } 

TestDll.cs:

public static class TestDll 
{ 
    (...) 
    [DllImport("test.dll", EntryPoint = "RegisterScaleUpdateCallback")] 
    public static extern void RegisterScaleUpdateCallback(int address); 
    (...) 
} 

[C++]

StrobeTest.h:

#pragma once 
class StrobeTest 
{ 
    typedef void (__stdcall *DROUpdate)(double x, double y, double z); 

private: 
    static DROUpdate s_CallbackFunction; 
public: 
    StrobeTest(void); 
    ~StrobeTest(void); 

    static void InitializeStrobe(void); 
    static void MoveXAtSpeed(double velocity); 
    static void CALLBACK RegisterScaleUpdateCallback(DROUpdate function); 
}; 

StrobeTest.cpp

(...) 
void StrobeTest::RegisterScaleUpdateCallback(DROUpdate function) 
{ 
    StrobeTest::s_CallbackFunction = function; 
    StrobeTest::s_CallbackFunction(1.0, 2.0, 3.0); 
} 
(...) 
+0

您不能使用MethodHandle.GetFunctionPointer()。更改RegisterScaleUpdateCallback()的聲明以獲取委託而不是int。 – 2013-05-07 23:25:23

+0

@Hans Passant謝謝,就是這樣!你碰巧知道爲什麼會出現這種情況?我以爲功能地址是一個功能地址。 – Mills 2013-05-07 23:33:49

+0

您必須通過一個存根切換到託管代碼執行,一個垃圾回收器詳細信息。而託管函數的調用約定是不同的,這是參數看起來錯誤的原因。基礎的核心方法是Marshal.GetFunctionPointerForDelegate()。 – 2013-05-08 00:08:31

回答

1

顯示TestDll的代碼,特別是其中的TestDll.RegisterScaleUpdateCallback的聲明。會有原因。確保調用約定匹配。