問題描述:
成都創(chuàng)新互聯(lián)不只是一家網(wǎng)站建設的網(wǎng)絡公司;我們對營銷、技術(shù)、服務都有自己獨特見解,公司采取“創(chuàng)意+綜合+營銷”一體化的方式為您提供更專業(yè)的服務!我們經(jīng)歷的每一步也許不一定是最完美的,但每一步都有值得深思的意義。我們珍視每一份信任,關(guān)注我們的做網(wǎng)站、成都網(wǎng)站設計質(zhì)量和服務品質(zhì),在得到用戶滿意的同時,也能得到同行業(yè)的專業(yè)認可,能夠為行業(yè)創(chuàng)新發(fā)展助力。未來將繼續(xù)專注于技術(shù)創(chuàng)新,服務升級,滿足企業(yè)一站式成都營銷網(wǎng)站建設需求,讓再小的品牌網(wǎng)站設計也能產(chǎn)生價值!1. C/C++ 寫的 DLL,其中有個方法(如MethodA)有的參數(shù)是回調(diào)函數(shù)。
2. C# 調(diào)用 DLL的方法MethodA,將自己的一個內(nèi)部方法(InnerMethod)作為回調(diào)函數(shù)的地址傳遞過去。
3. 當 InnerMethod 被觸發(fā)時,往往第一次能成功,再次觸發(fā)時就會崩潰,報的錯誤為非法內(nèi)存訪問之類。
碰到以上錯誤,估計你的大腦也會像內(nèi)存一樣:奔潰??赡軙L試各種辦法:修改 C/C++ 代碼,將方法加上 _stdcall;修改 C# 代碼,調(diào)整調(diào)用約定;修改 InnerMethod,增加各種調(diào)試,改用臨時變量,改用全局變量,只做計算,不訪問其它資源。。。最后呢,還是奔潰。
我當時就被這個問題折磨了好幾天,而同事的 QT 調(diào)用 DLL 卻正常,這說明問題還是出在?C# 上。后來經(jīng)過多方查找,發(fā)現(xiàn)是 C# 的GC的問題,是GC把C#內(nèi)的回調(diào)函數(shù)回收了,當下次DLL再次調(diào)用這個函數(shù)時,就會觸發(fā)非法內(nèi)存訪問的錯誤。
如何修復呢?強制GC保留它,等到最后才回收。一般,出問題的的代碼如下:
///
/// 調(diào)用 DLL 的方法(參數(shù)為回調(diào)函數(shù)地址)
///
private void CallDll()
{
?DllMethodA(OnCallBack); ? ? ? ? ? ?
}
///
/// 給 DLL 的回調(diào)函數(shù)
///
///
private void OnCallBack(int retValue)
{
?Console.WriteLine($@"the return value from the dll is {retValue}");
}
將代碼修改如下:
// 聲明委托,
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void MethodCallbackEvent(int i);
private static MethodCallbackEvent _callbackFunc = null;
private static GCHandle _gcHandle = new GCHandle();
///
/// 調(diào)用 DLL 的方法(參數(shù)為回調(diào)函數(shù)地址)
///
private void CallDll()
{
?// 讓 GC 保留,不回收這個回調(diào)函數(shù)
?_callbackFunc = new MethodCallbackEvent(OnCallBack);
?_gcHandle = GCHandle.Alloc(_callbackFunc);
?DllMethodA(_callbackFunc);
}
///
/// 給 DLL 的回調(diào)函數(shù)
///
///
private void OnCallBack(int retValue)
{
?Console.WriteLine($@"the return value from the dll is {retValue}");
}
///
/// 增加一個釋放的方法,在合適的時候調(diào)用
///
private void ReleaseCallback()
{
?if (_gcHandle.IsAllocated) { _gcHandle.Free(); }
}
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧