2014-05-24 54 views
1

我將在運行時加載OCX並將加載的ocx的句柄傳遞給另一個函數,這是一個補丁, 我有delphi代碼,它工作正常,我想將它轉換爲C#,但我不知道該怎麼動態加載OCX並獲取C#中加載模塊的句柄

Type  
    TDLLFunc = procedure(param1: dword); 
VAR 
    DLLFunc  : TDLLFunc; 
    OcxDllHndle : LongInt; 
    DllHandle : LongInt; 

begin 
    OcxDllHndle := LoadLibrary('SampleOcx.Dll'); 
    DllHandle := LoadLibrary('Patch.dll'); 
    @DLLFunc := GetProcAddress(DllHandle, 'DoPatch'); 
    DLLFunc(OcxDllHndle); 
end; 

這裏是C#代碼,但它不工作(我做了OCX的AxInterop版):

AppDomain Domain = AppDomain.CreateDomain("TestApp", null, null); 
var assemblyName = AssemblyName.GetAssemblyName(@".\AxInterop.SampleOcx.dll"); 
Assembly Ocx = Assembly.Load(assemblyName); 
IntPtr DLLHandle = LoadLibrary(Application.StartupPath + @"\Patch.dll"); 
IntPtr funcaddr = GetProcAddress(DLLHandle, "DoPatch"); 

[UnmanagedFunctionPointer(CallingConvention.StdCall)] 
delegate void MyFunc(int Handle); 

MyFunc DLLFunc = Marshal.GetDelegateForFunctionPointer(funcaddr, typeof(MyFunc)) as MyFunc; 
IntPtr OCXHandle = Marshal.GetHINSTANCE(Ocx.GetType().Module); 
DLLFunc(OCXHandle.ToInt32()); 

請幫助

+0

你不做任何錯誤檢查。你怎麼能告訴它失敗?下一步是檢查錯誤。閱讀您所做API調用的文檔以瞭解如何。我也想知道爲什麼你會調用LoadLibrary。直接捏住它並讓框架加載庫。 –

+0

謝謝大衛,其實我在代碼示例中沒有提到它的行中檢查它,當補丁運行時,隨後對ocx函數的調用將返回適當的值,並且在上面的示例中,ocx函數不會返回適當的價值。 –

回答

0

從該Delphi DLL導出的函數不能從C#調用。 Delphi DLL使用register調用約定導出函數,該約定是非標準的Delphi唯一調用約定。您將需要修改DLL以使用例如stdcall進行導出。

假設你進行更改的C#代碼應該是這樣的:

[DllImport("patch.dll")] 
static extern void DoPatch(IntPtr moduleHandle); 
.... 
IntPtr OcxHandle = LoadLibrary("SampleOcx.dll"); 
if (OcxHandle == IntPtr.Zero) 
    .... handle error 
DoPatch(OcxHandle); 

注意這個參數是不是一個真正的DWORD。這是一個HMODULE。這是64位進程下的64位類型。這使我指出你的程序必須針對x86來處理你的32位Delphi DLL。 OCX大概也是32位。

+0

我明白了,但是如何在調用LoadLibrary之後獲得ocx的實例? –

+0

我的代碼證明了這一點。 LoadLibrary返回的值是實例。 C#代碼與Delphi代碼相同。 –