2010-05-12 38 views
6

Tôi đang sử dụng dll không được quản lý bên ngoài bằng cách sử dụng thuộc tính PInvoke và DllImport. ví dụ.Đặt thuộc tính DllImport động

[DllImport("mcs_apiD.dll", CharSet = CharSet.Auto)] 
private static extern byte start_api(byte pid, byte stat, byte dbg, byte ka); 

Tôi tự hỏi nếu nó có thể thay đổi các chi tiết tập tin dll (mcs_apiD.dll trong ví dụ này) dynmically trong một số cách, nếu ví dụ tôi muốn xây dựng lại một phiên bản dll

Trả lời

2

bạn có thể không thay đổi tên của dll nhưng bạn có thể thay đổi đường dẫn của thư viện đang được nạp (như đọc nó từ sổ đăng ký hoặc tệp cấu hình) và tải nó theo cách thủ công với hàm LoadLibrary kernel32: see my answer there.

+0

Ok. Nhưng trong ví dụ của tôi, tôi đã chỉ định một nguyên mẫu hàm cụ thể để tôi có thể marsall các tham số một cách chính xác, một số hàm api có cấu trúc phức tạp như các tham số. Làm thế nào tôi sẽ làm điều này khi làm việc theo cách này? – user226356

+0

nếu các thông số thay đổi từ một phiên bản của DLL sang một phiên bản khác, bạn không may mắn với phương pháp tôi đã đề cập –

5

Có điều này là có thể, bạn sẽ phải thực hiện một phần công việc mà P/Invoke marshaller thực hiện. Tải DLL và tìm điểm vào của hàm được xuất. Bắt đầu bằng cách tuyên bố một đại biểu có chữ ký phù hợp với chức năng xuất khẩu:

private delegate byte start_api(byte pid, byte stat, byte dbg, byte ka); 

Sau đó sử dụng mã như thế này:

using System.ComponentModel; 
using System.Runtime.InteropServices; 
    ... 

    static IntPtr dllHandle; 
    ... 
     if (dllHandle == IntPtr.Zero) { 
      dllHandle = LoadLibrary("mcs_apiD.dll"); 
      if (dllHandle == IntPtr.Zero) throw new Win32Exception(); 
     } 
     IntPtr addr = GetProcAddress(dllHandle, "[email protected]"); 
     if (addr == IntPtr.Zero) throw new Win32Exception(); 
     var func = (start_api)Marshal.GetDelegateForFunctionPointer(addr, typeof(start_api)); 
     var retval = func(1, 2, 3, 4); 
    ... 
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
    private static extern IntPtr LoadLibrary(string name); 
    [DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)] 
    private static extern IntPtr GetProcAddress(IntPtr hModule, string name); 

Rất nhiều cách để có được sai này tất nhiên. Do lưu ý rằng bạn phải sử dụng tên xuất khẩu thực tế từ DLL, bạn không còn nhận được sự trợ giúp từ P/Invoke marshaller để giúp trang trí tên. Sử dụng dumpbin.exe/xuất khẩu trên DLL nếu bạn không chắc chắn tên xuất khẩu trông như thế nào.

+0

, với 1 loại đại biểu cho mỗi phiên bản của DLL API kết hợp với GetProcAddress, bạn sẽ thoát ra khỏi it –

+0

Có một bài viết trên blog của Microsoft về vấn đề này tại: http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_ .aspx – Deanna

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