惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
Google DeepMind News
Google DeepMind News
MyScale Blog
MyScale Blog
A
About on SuperTechFans
Martin Fowler
Martin Fowler
M
MIT News - Artificial intelligence
Recent Announcements
Recent Announcements
D
DataBreaches.Net
B
Blog
博客园 - 【当耐特】
爱范儿
爱范儿
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
WordPress大学
WordPress大学
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
Engineering at Meta
Engineering at Meta
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Last Week in AI
Last Week in AI
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网
量子位
G
Google Developers Blog

博客园 - 同洲共际海让路

国内首本全面深入介绍.NET互操作技术(P/Invoke『或PInvoke,平台调用』,C++ Interop『C++/CLI』,COM Interop)的参考书籍 博客园开发者征途系列图书——《你必须知道的.NET》 一站式查询八字、五行、星座、五格——美名腾人名解析 一句话让别人立马记住你的名字——美名腾智能人名解析 何谓智能起名? 美名腾智能起名系统有了新界面 千名万名,到美名腾来试金。【写在美名腾起名系统Beta版成功发布】 [原]Bug Report,已提交给微软。平台调用调试时,无法对非托管函数进行单步的错误 [原]动态平台调用 part 3 (Final) [原]动态平台调用 part 2 JavaScript Debugging and Intellisense, JavaScript obfuscator etc from VS 2005 to VS 2008 (VS2005到2008的变迁,JavaScript调试,智能感知/智能感应功能,JavaScript的混淆、压缩等功能的海变桑田) 终于见到了传说中的Scott Guthrie 如何为Team Foundation Server的Daily Build添加自定义操作 客户端安装Team Explorer 2005后,使用时出现package load failure错误的修正 WCF Part 7 : Bindings WCF Part 6 : Address 推荐一个好玩的好东西,ILMerge,微软出的,合并多个.NET组件成一个 WCF Part 5 : Consuming the service [译]WCF Part 4 : Make your service visible through metadata
[原]动态平台调用 part 1
同洲共际海让路 · 2008-07-21 · via 博客园 - 同洲共际海让路

     对非托管函数进行平台调用,最小要求就是要为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.

     未完待续......