2011-09-30 29 views
6

Trong C#, tôi đang cố gắng để PInvoke một "đơn giản" chức năng tôi có trong C + +. Vấn đề là tôi không biết tên hoặc vị trí của thư viện vào thời gian biên dịch. Trong C++, điều này rất dễ dàng:PInvoke khi bạn không biết DLL tại thời gian biên dịch?

typedef HRESULT (*SomeFuncSig)(int, IUnknown *, IUnknown **); 

const char *lib = "someLib.dll"; // Calculated at runtime 

HMODULE mod = LoadLibrary(lib); 
SomeFuncSig func = (SomeFuncSig)GetProcAddress("MyMethod"); 

IUnknown *in = GetSomeParam(); 
IUnknown *out = NULL; 
HRESULT hr = func(12345, in, &out); 

// Leave module loaded to continue using foo. 

Vì cuộc sống của tôi, tôi không thể tìm ra cách thực hiện điều này trong C#. Tôi sẽ không có bất kỳ rắc rối nếu tôi biết tên dll, nó sẽ trông một cái gì đó như thế này:

[DllImport("someLib.dll")] 
uint MyMethod(int i, 
       [In, MarshalAs(UnmanagedType.Interface)] IUnknown input, 
       [Out, MarshalAs(UnmanagedType.Interface)] out IUnknown output); 

Làm thế nào để làm điều này mà không biết dll Tôi tải từ lúc biên dịch?

Trả lời

5

Ngài là một giải pháp ở đây: Dynamically calling an unmanaged dll from .NET (C#) (dựa trên LoadLibrary/GetProcAddress)

+0

Tôi có thiếu gì đó không? Để sử dụng LoadLibrary bạn * làm * cần phải biết tên của dll. Nếu OP _knew_ tên của dll anh ta sẽ không cố gắng và tìm thấy một giải pháp khác nhau ở nơi đầu tiên. Chỉnh sửa: nghĩ rằng tôi đã bỏ lỡ "tại thời gian biên dịch" so với "lúc chạy". –

7

Bạn làm điều đó theo cùng một cách. Khai báo kiểu ủy nhiệm có chữ ký khớp với hàm được xuất, giống như SomeFuncSig. Pinvoke LoadLibrary và GetProcAddress để lấy IntPtr cho hàm được xuất, giống như bạn đã làm trong C++. Sau đó tạo đối tượng delegate với Marshal.GetDelegateForFunctionPointer().

1

Nếu bạn biết tên DLL trước, và bạn biết trước tên hàm, có một cách đơn giản hơn.

Bạn có thể chỉ cần khai báo chữ ký P/Invoke, sau đó sử dụng LoadLibrary để tải DLL dựa trên ví dụ như một mục nhập tệp cấu hình. Miễn là bạn gọi thành công LoadLibrarytrước bất kỳ chức năng P/Invoke nào được sử dụng, chúng sẽ thành công khi DLL đã được tải.

Các vấn đề liên quan