我有一個棘手的錯誤,我找不到。我正在從C#到我編寫的本地DLL綁定。 後期綁定似乎工作正常。我添加回調後出現問題。C到C#的回調在一段時間後引發異常
的回調定義爲這樣(在C)(在DLL中全球範圍):
typedef void (*FinishedDelegate) (ProcessResult a_bResult);
typedef void (*DownloadStatusUpdateDelegate) (int a_iParametersDownloaded, int a_iTotalParameters);
typedef void (*DownloadFinishedDelegate) (char* a_sConfiguration_values, ProcessResult a_bResult);
DownloadStatusUpdateDelegate pfDownloadStatusUpdateDelegate = NULL;
DownloadFinishedDelegate pfDownloadFinishedDelegate = NULL;
此功能輸出:
PLUGIN_API BOOL DownloadConfigration(DownloadStatusUpdateDelegate a_pfStatusDelegate, DownloadFinishedDelegate a_pfFinishedDelegate);
這是本機功能的實現:
DWORD WINAPI DownloadThreadFunc(void* a_pParam)
{
while (g_iParameterDownloaded < PARAMETER_COUNT)
{
if (IsEventSignaled(g_hAbortEvent))
{
CallDownloadFinished(PROCESS_ABORT);
return 0;
}
Sleep(STATUS_DELAY);
CallDownloadStatusUpdate();
g_iParameterDownloaded += STATUS_PARAMS_JUMP;
}
CallDownloadFinished(PROCESS_SUCCESS);
return 0;
}
PLUGIN_API BOOL DownloadConfigration(DownloadStatusUpdateDelegate a_pfStatusDelegate, DownloadFinishedDelegate a_pfFinishedDelegate)
{
if (IsEventSignaled(g_hInProcessEvent))
return false;
pfDownloadStatusUpdateDelegate = a_pfStatusDelegate;
pfDownloadFinishedDelegate = a_pfFinishedDelegate;
g_iParameterDownloaded = 0;
DWORD l_dwResult = WaitForSingleObject(g_hThreadsStructGuardian, INFINITE);
if (l_dwResult == WAIT_OBJECT_0)
{
g_ahThreads[PLUGIN_THREAD_DOWNLOAD] = CreateThread(NULL, 0, DownloadThreadFunc, 0, 0, NULL);
ReleaseMutex(g_hThreadsStructGuardian);
return true;
}
return false;
}
在管理端,功能在這裏稱爲:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DownloadStatusUpdateDelegate(int a_iParametersDownloaded, int a_iTotalParameters);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void DownloadFinishedDelegate_Native(StringBuilder a_sConfigurationValues, EPluginProcessResult a_eResult);
private void OnDownloadStatusUpdate(int a_iParametersDownloaded, int a_iTotalParameters)
{
if (DownloadStatusUpdate != null)
{
DownloadStatusUpdate(a_iParametersDownloaded, a_iTotalParameters);
}
}
private void OnDownloadFinished(StringBuilder a_sConfigurationValues, EPluginProcessResult a_eResult)
{
if (DownloadFinished != null)
{
DownloadFinished(a_sConfigurationValues.ToString(), a_eResult);
}
}
public bool DownloadConfiguration()
{
bool l_bResult = DLLDownloadConfigration(OnDownloadStatusUpdate, OnDownloadFinished);
return l_bResult;
}
奇怪的是 - 它工作了一段時間。一段時間後,我會得到一個「特權指令」異常,但是當我降低STATUS_DELAY時,發生的情況會更少。異常顯示在IsEventSignaled函數 - 但沒有什麼。
下載線程會同步到c#GUI線程以更新GUI。
我一直在這個問題上的方式太多的時間。它看起來像一個經典的調用約定問題,但我徹底驗證了它!
任何想法?
是的,就是這樣 - 你不能將託管函數傳遞給非託管代碼。這就是爲什麼我首先定義了這些代表。 – Nitay
對不起,在代碼混亂。謝謝你的幫助! – Nitay