簡體   English   中英

在動態加載的DLL庫中返回字符串失敗

[英]Returning string in dynamically loaded DLL library fails

我將完全向您描述我的問題和過程。 我當時正在為他人的游戲進行編輯,並且我有一個用C語言編寫的包裝DLL與我交流。

最初,我有從DLL調用DllImport函數的方法列表。 第一個方法是CSharp_new_CEditorInterface ,它返回IntPtr 然后CSharp_CEditorInterface_CreateApp這托克ulong處理到窗口控制,其中將繪制圖形。 最后我應該叫CSharp_CEditorInterface_CloseAppCSharp_delete_CEditorInterface 這些方法采用HandleRef ,其指針從CSharp_new_CEditorInterface返回。

但是,我需要多次調用創建和刪除方法,當第二次調用CSharp_CEditorInterface_CreateApp時,它引發了System.AccessViolationException 因此,我決定使用LoadLibrary和FreeLibrary動態地加載和卸載DLL。 我編寫了一個應用程序,通過反射瀏覽了所有p / invoke方法,並生成了由委托,只讀字段和GetProcAddress-es組成的代碼。 但是,正如我發現的那樣,入口點只是部分的。 CSharp_new_CEditorInterface_CSharp_new_CEditorInterface@0 使用DLL導出查看器,我保存了所有完整的函數名稱,然后在其中搜索。 在構造函數中,我調用LoadLibrary並調用適當的函數。 Dispose ,有FreeLibrary

該解決方案運行良好,將函數稱為OK,直到發現返回字符串的某些函數拋出AccessViolationException為止。 使用DllImport方法時,它們可以正常工作。 我還發現,當從靜態類調用ANY函數,從而加載另一個模塊時,調用有問題的函數現在可以了,並且它們返回適當的值。 但是,動態卸載DLL並重新加載后,它無法再次工作並猜測拋出了哪個異常。

現在我調用哪個函數,順序如何:

--When initializing--
LoadLibrary(string)  (winapi)
--bunch of GetProcAddress, Marshal.GetDelegateForFunctionPointer--
new_CEditorInterface()  (from DLL)
CreateApp(HandleRef, ulong)  (from DLL)

--When closing in Dispose--
CloseApp(HandleRef)  (from DLL)
delete_CEditorInterface(HandleRef)  (from DLL)
FreeLibrary(IntPtr)  (winapi)

我應該注意,DLL並非一次加載多個。

有人可以幫我嗎?

試試這個,希望對您有幫助

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr LoadLibrary(string libname);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool FreeLibrary(IntPtr hModule);

//Load
IntPtr Handle = LoadLibrary(fileName);
if (Handle == IntPtr.Zero)
{
     int errorCode = Marshal.GetLastWin32Error();
     throw new Exception(string.Format("Failed to load library (ErrorCode: {0})",errorCode));
}

//Free
if(Handle != IntPtr.Zero)
        FreeLibrary(Handle);

如果要先調用函數,則必須創建與此函數匹配的delegeate,然后使用WinApi GetProcAddress

[DllImport("kernel32.dll", CharSet = CharSet.Ansi)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); 


IntPtr funcaddr = GetProcAddress(Handle,functionName);
YourFunctionDelegate function = Marshal.GetDelegateForFunctionPointer(funcaddr,typeof(YourFunctionDelegate )) as YourFunctionDelegate ;
function.Invoke(pass here your parameters);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM