同洲共际海让路@小舟侧盼千帆过,扬帆寻她千百度
+U, 抬头仰望,低头思索@同洲共际海让路

     对非托管函数进行平台调用,最小要求就是要为DllImport属性传入包含所要调用的非托管函数的DLL的名称。DLL的名称,可以是DLL的绝对路径,如DllImport(@"D:"BookCode"NativeLib.dll")。也可以是DLL的相对路径,如DllImport("NativeLib.dll")。当指定为相对路径时,CLR会在以下搜索路径下搜索这个非托管DLL。首先,CLR会在当前目录下搜索这个非托管DLL。如果没找到,就会转向搜索Windows系统目录。如果还没有找到,则会在PATH环境变量所列出的所有目录中进行搜索。如果在上述所列出的所有目录中都没有找到这个DLL时,CLR就会抛出一个DllNotFoundException。由此可见,如果要调用的非托管函数没有位于所有可供搜索的路径之下,那么就无法对非托管函数进行平台调用。

      仔细分析平台调用的过程和原理,就能直观地想出一个进行动态平台调用的方法。那就是在对非托管DLL中的函数进行平台调用之前,也就是CLR开始在默认搜索路径下搜索非托管DLL并使用Win32 API LoadLibrary加载此DLL之前,手动地使用LoadLibrary来加载非托管DLL。这样CLR就能搜索到这个非托管DLL,并对其中指定的非托管函数进行平台调用了。

 

class DynamicPInvokeViaLoadLib

{

[DllImport("NativeLibForDynamicPInvoke.dll")]

static extern int Multiply(int factorA, int factorB);

 

public static void Test()

{

string currentDirectory =

                            Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

 

string dllPath = Path.Combine(currentDirectory,

                            @"nativelibfordynamicpinvoke"NativeLibForDynamicPInvoke.dll");

IntPtr dllAddr = Win32API.LoadLibrary(dllPath);

 

if (dllAddr == IntPtr.Zero)

{

throw new DllNotFoundException(

string.Format("Can not load {0}, please check.", dllPath));

}

 

//调用非托管函数

int factorA = 100, factorB = 8;

int result = Multiply(factorA, factorB);

 

//打印结果

Console.WriteLine(string.Format("{0} * {1} = {2} ", factorA, factorB, result));

 

Console.WriteLine("Press any key to exit.");

Console.Read();

}

}

 

其中LoadLibrary是在Win32API类中进行声明的Win32 API函数,其定义如下:

[DllImport("kernel32.dll", EntryPoint = "LoadLibrary")]

public static extern IntPtr LoadLibrary(

string lpLibFileName

);

 

如同之前进行平台调用时一样,首先在托管代码中对需要调用的非托管函数进行声明,并为其加上DllImport属性。在为DllImport属性传入包含所要调用的非托管函数的DLL的名称时,使用相对路径,只传入了非托管DLL的名称。由于这个DLL并不在CLR的默认搜索路径下,因此CLR就不能搜索到它并使用LoadLibrary来加载它了。解决这个问题的办法就是在对非托管DLL中的函数进行平台调用之前,手动地使用LoadLibrary来加载非托管DLL。上面代码中的粗体部分就演示了这种方法。

运行DynamicPInvokeViaLoadLib类的Test方法进行测试,就能得到如下的结果:

100 * 8 = 800

Press any key to exit.

 

     未完待续......

   

posted on 2008-07-21 12:09  同洲共际海让路  阅读(761)  评论(2编辑  收藏  举报