2013-04-28 137 views
2

我想從非託管代碼調用託管方法。但是,託管代碼要求我使用'(__clrcall)調用約定,而我的非託管C++代碼拒絕讓我使用__clrcall調用約定而不使用/ clr選項。我不相信我想這樣做,因爲非託管項目不是我的需要改變爲託管。卡住調用從非託管C++調用託管CLI方法

我已經通過在CodeGuru和MSDN上看到的構造了託管端的所有這些委託和函數指針封送,但是這個錯誤仍然會彈出,除非我使用__stdcall約定不能成爲靜態函數一個ref類。該方法需要是ref類的一個實例。

我已經能夠解決這個問題的唯一方法是從程序集中的非託管代碼執行我的方法調用,在調用之後跳過ESP寄存器的彈出(添加4)(該調用在參數中有一個參數因此'4')。這可以讓我有效地做一個__clrcall。這個選項讓人感到很難過。

任何人有關於如何解決此問題的任何想法?它一定是可能的。我錯過了一些簡單而重要的信息。

這裏是我的委託定義(所有這些屬於一個引用類ManagedSensor):

 delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes); 

這裏是實例方法我想打電話給

 void LocalOxpMeasurementCallback(std::vector<OBX> *obxes); 

這裏是封送處理的ref類函數在ref類構造函數中完成的非託管函數:

// Now to make the 'delegate' unmanaged function pointer usable for unmanged code 
    // The argument is the unmanaged callback. 
    OxpOnReceivedMeasurement ^oxpMeasurementCallbackFP = gcnew OxpOnReceivedMeasurement(this, &ManagedSensor::LocalOxpMeasurementCallback); 
    // Lock it so the garbage collector doesnt get rid of it or move it 
    gch = GCHandle::Alloc(oxpMeasurementCallbackFP); 
    // Pass the marshaled function pointer to the unmanaged code 
    IntPtr ip = Marshal::GetFunctionPointerForDelegate(oxpMeasurementCallbackFP); 
    // fnOnReceiveMeasurement is defined in OxpLibTransports.h which matches the delegate 
    // this passes the function pointer to the unmanaged Sensor class to be used when a 
    // measurement is received 
    _sensor->RegisterForMeasurementCallback((fnOnReceiveMeasurement)(ip.ToPointer())); 

希望有人對此問題有一個很好的答案。我可能錯過了一些愚蠢的東西。

回答

6

支持。你可以使用一個屬性告訴CLR它爲它創建的thunk應該使用__cdecl調用約定。使它看起來像這樣:

using namespace System::Runtime::InteropServices; 

[UnmanagedFunctionPointer(CallingConvention::Cdecl)] 
delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes); 
+0

再次感謝!兩次不到24小時。這比在線裝配好得多,可以消除單個添加esp,4聲明。非常感激。 – 2013-04-28 20:38:15