2014-10-29 32 views
-1

有在本機代碼以下,需要在託管代碼編寫:如何P /調用一個可能不存在的函數?

HINSTANCE hUser = LoadLibrary("user32.dll"); /* Can't fail -- it's already loaded */ 
BOOL (*dpi)() = (BOOL (*)())GetProcAddress(hUser, "SetProcessDPIAware"); 
if(dpi) dpi(); 

功能SetProcessDPIAware沒有最低端的平臺,我們支持上存在的,所以我們會碰到裝載機問題簡單地聲明函數並試圖稱它。

但是,我必須根據除操作系統版本以外的條件調用SetProcessDPIAware來做出運行時決定,所以我不能使用清單。

+0

的解決方案是讓'GetProcAddress'爲P/Invoke的功能以及,並調用從託管代碼。 – Dai 2014-10-29 21:46:01

+0

重複標記不正確,因爲重複問題沒有我可以使用的答案。 – Joshua 2014-10-29 22:16:16

+1

不要這樣做,使用清單。總是更好。 – 2014-10-29 22:51:03

回答

1

你可以P /調用LoadLibraryGetProcAddress以類似的方式:

using System; 
using System.Runtime.InteropServices; 

static class Program 
{ 
    [DllImport("kernel32", SetLastError = true)] 
    static extern IntPtr LoadLibrary(string lpFileName); 

    [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] 
    static extern IntPtr GetProcAddress(IntPtr hModule, string procName); 

    delegate bool MyDelegate(); 

    static void Main() 
    { 
     var hUser = LoadLibrary("user32.dll"); 
     var res = GetProcAddress(hUser, "SetProcessDPIAware"); 
     if (res != IntPtr.Zero) 
     { 
      // The function we are looking for exists => 
      // we can now get the corresponding delegate and invoke it 
      var del = (MyDelegate)Marshal.GetDelegateForFunctionPointer(res, typeof(MyDelegate)); 

      bool x = del(); 
      Console.WriteLine(x); 
     } 
    } 
} 
相關問題