2012-08-11 86 views
0

我將完全描述你我的問題和過程。我正在爲另一個人的遊戲製作一個編輯器,並且我有一個用C語言編寫的包裝器DLL,我正在與之通信。在動態加載的DLL庫中返回字符串失敗

起初我有方法列表DllImport從DLL調用函數。第一種方法是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[email protected]。使用我的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加載一個超過一次。

有人可以幫我嗎?

+0

您可以顯示一些真正的代碼,你實際使用,並指出你在哪裏得到問題的代碼,這是有點難/很長的跟隨顯示代碼通常更容易爲別人提供幫助經文sudo編碼..也看看單身人士和或如何爲si創建互斥鎖代碼爲 – MethodMan 2012-08-11 18:00:15

+0

的實例運行我想我已經描述了所需的一切。返回字符串的非託管方法在通過DllImport調用時工作正常,但在通過GetProcAddress指針調用時失敗。使用DllImport加載指定的DLL時,該方法正常工作,直到卸載並重新加載。 – IllidanS4 2012-08-11 20:10:00

回答

0

試試這個,我希望這可以幫助你

[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); 
+0

感謝您的努力,但我擁有所有必要的代表職能。我也檢查過,句柄不爲零。我確定。其他功能加載了samy的方式工作。只是那些返回字符串。也許MarshalAs可以以某種方式解決這個問題? – IllidanS4 2012-08-14 12:04:16