背景:C#網站專案呼叫C++dll,dll中封裝了網路庫,網路庫里有用mfc,vc的函式,另外dll中的業務執行緒用的是c++11標準庫函式。
問題:
1.c#呼叫c++介面函式,引數為方便c++回呼的回呼函式,如void (F f)這種形式。現在已經確定C#呼叫C++介面沒有問題,問題是如果我在C++執行緒里呼叫C#向C++注冊的回呼函式,如果C++執行緒是用AfxBeginThread函式創建的執行緒程式會崩潰,我也是崩潰了,如果是用標準庫std::thread創建的執行緒就不會。求解原因。
2.當關閉C#控制臺應用程式的時候,C++解構式里面用到鎖相關的函式程式都會崩潰,提示netdll.dll錯誤,試了很多方法都不行,現在臨時的解決辦法就是在C++解構式里面停止業務執行緒(業務執行緒是用std::thread創建的,網路執行緒是用AfxBeginThread)后程式sleep個5秒(3秒都不行)。求大神幫忙解決下哦。
uj5u.com熱心網友回復:
一般不直接在dll中開執行緒,只做呼叫某個方法,立即回傳結果。實在不行exe中開好執行緒,呼叫dll的方法。
1 可能是mfc某些東西沒初始化
2 增加一個dll方法,停止dll里面的一切,停止后再退出
uj5u.com熱心網友回復:
C# 的 delegate ,呼叫約定規定清楚了嗎uj5u.com熱心網友回復:
托管和非托管之間耦合的這么緊嗎uj5u.com熱心網友回復:
afxbeginthread 我記得他的執行緒函式是UINT method(LPARAM)形式uj5u.com熱心網友回復:
主要是MFC跟c#一些沖突什么的uj5u.com熱心網友回復:
呼叫約定cdcal,stdcal之內的都調好了
uj5u.com熱心網友回復:
表現形式是整個程式崩潰,報c++dll錯誤
uj5u.com熱心網友回復:
dll里面封裝的是之前一個娃寫的iocp網路庫,c++用來做二進制資料處理,結果以回掉函式方式回傳給c#
uj5u.com熱心網友回復:
我感覺他既然用到了afxbeginthread,估計是一個擴展的mfc dll形式。如果是擴展mfc dll形式,C#好像很難完美的呼叫,解決方案,寫一個純c的exe,呼叫這個dll,看出不出錯?如果不出,把這個c的exe改為dll,再次封裝一下。
uj5u.com熱心網友回復:
我現在對問題中第二個現象有些懷疑,是不是C#垃圾回識訓制造成的,是不是關閉程式的時候C++立即呼叫洗狗函式把執行緒停掉了,等C#在垃圾回收的時候找不到C++創建執行緒系統自動與C#關聯的一些東西(到底是什么東西),就報netdll.dll錯誤,在c++中sleep個5秒,等C#垃圾回收完成再呼叫C++洗狗就可以了。根據這個思路,我在c# main函式關閉視窗事件中加入GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
悲劇的仍然沒有用
uj5u.com熱心網友回復:
用C++exe呼叫這個dll是不會出錯的,我就是比較奇怪為啥子我在業務執行緒里用c++標準庫函式std::thread就不會出錯
uj5u.com熱心網友回復:
你看一下這個吧uj5u.com熱心網友回復:
沒有使用 C++/CLI, MFC間接跟 CLR 互作,是否需要設定不清楚, 不過你可以試一下。在鏈接設定, 高級, CLR Thread Attribute 處選擇 STA
uj5u.com熱心網友回復:
這種互動,少用MFC,最好不用。uj5u.com熱心網友回復:
不要做A語言代碼修改為B語言代碼的無用功。也不要做用A語言代碼直接呼叫B語言代碼庫這樣復雜、這樣容易出錯的傻事。
只需讓A、B語言代碼的輸入輸出重定向到文本檔案,或修改A、B語言代碼讓其通過文本檔案輸入輸出。
即可很方便地讓A、B兩種語言之間協調作業。
比如:
A將請求資料寫到檔案a.txt,寫完后改名為aa.txt
B發現aa.txt存在時,讀取其內容,呼叫相應功能,將結果寫到檔案b.txt,寫完后洗掉aa.txt,改名為bb.txt
A發現bb.txt存在時,讀取其內容,讀完后洗掉bb.txt
以上A可以替換為任何一種開發語言或開發環境,B可以替換為任何一種與A不同的開發語言或開發環境。
除非A或B不支持判斷檔案是否存在、檔案讀寫和檔案更名。
但是誰又能舉出不支持判斷檔案是否存在、檔案讀寫和檔案更名的開發語言或開發環境呢?
可以將臨時檔案放在RamDisk上提高效率減少磨損磁盤。
資料的結構很復雜的話,文本檔案的格式問題可參考json或xml
共享臨時文本檔案這種行程之間的通訊方法相比其它方法的優點有很多,下面僅列出我現在能想到的:
·行程之間松耦合
·行程可在同一臺機器上,也可跨機,跨作業系統,跨硬體平臺,甚至跨國。
·方便除錯和監視,只需讓第三方或人工查看該臨時文本檔案即可。
·方便在線開關服務,只需洗掉或創建該臨時文本檔案即可。
·方便實作分布式和負載均衡。
·方便佇列化提供服務,而且幾乎不可能發生佇列滿的情況(除非硬碟空間滿)
·……
“跨語言、跨機,跨作業系統,跨硬體平臺,跨國,跨*.*的”苦海無邊,
回頭是“使用共享純文本檔案進行資訊交流”的岸!
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/112487.html
標籤:進程/線程/DLL
