使用 GetProcAddress Function 时,有以下几点需要特别留意:

1. 第二个参数类型是 LPCSTR,不是 ;

2. 用 __declspec(dllexport),按 C 名称修饰(extern "C")
导出的函数名,对于 __stdcall 和 __fastcall 调用约定是相同的;对 __cdecl 是不同的(导出的函数名没有前面的下划线);

3. 即使返回值不是 NULL,也有可能发生错误。当 .def 模块不是连续地从 1 开始编号 ordinal 值,那么,如果用一个无函数对应的 ordinal 值调用 GetProcAddress,就会发生错误,返回一个无效的非 NULL 地址; 

4. 最好用函数名,而不是 ordinal 值调用 GetProcAddress,以避免不同版本 Dll 中某些函数不存在的情况。

注:确认 Dll 的导出函数名,可以用 DUMPBIN /EXPORTS dll_file_name.dll 命令,然后查看 name 列。

[cpp] view plain copy

 print?

  1. // The myPuts function writes a null-terminated string to  
  2. // the standard output device.  
  3.    
     
  4. // The export mechanism used here is the __declspec(export)  
  5. // method supported by Microsoft Visual Studio, but any  
  6. // other export method supported by your development  
  7. // environment may be substituted.  
  8.    
     
  9.    
     
  10. #include <windows.h>  
  11.    
     
  12. #define EOF (-1)  
  13.    
     
  14. #ifdef __cplusplus    // If used by C++ code,   
  15. extern "C" {          // we need to export the C interface  
  16. #endif  
  17.    
     
  18. __declspec(dllexportint __cdecl myPuts(LPTSTR lpszMsg) // __cdecl | __stdcall | __fastcall  
  19. {  
  20.     DWORD cchWritten;  
  21.     HANDLE hStdout;  
  22.     BOOL fRet;  
  23.    
     
  24.     // Get a handle to the standard output device.  
  25.    
     
  26.     hStdout = GetStdHandle(STD_OUTPUT_HANDLE);  
  27.     if (INVALID_HANDLE_VALUE == hStdout)  
  28.         return EOF;  
  29.    
     
  30.     // Write a null-terminated string to the standard output device.  
  31.    
     
  32.     while (*lpszMsg != '\0')  
  33.     {  
  34.         fRet = WriteFile(hStdout, lpszMsg, 1, &cchWritten, NULL);  
  35.         if( (FALSE == fRet) || (1 != cchWritten) )  
  36.             return EOF;  
  37.         lpszMsg++;  
  38.     }  
  39.    
     
  40.     return 1;  
  41. }  
  42.    
     
  43. #ifdef __cplusplus  
  44. }  
  45. #endif  

[cpp] view plain copy

 print?

  1. // A simple program that uses LoadLibrary and   
  2. // GetProcAddress to access myPuts from Myputs.dll.   
  3.    
     
  4. #include <stdio.h>   
  5. #include <windows.h>   
  6.    
     
  7. typedef int (__cdecl *MYPROC)(LPTSTR); // __cdecl | __stdcall | __fastcall  
  8.    
     
  9. VOID main(VOID)   
  10. {   
  11.     HINSTANCE hinstLib;   
  12.     MYPROC ProcAdd;   
  13.     BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;   
  14.    
     
  15.     // Get a handle to the DLL module.  
  16.    
     
  17.     hinstLib = LoadLibrary(TEXT("bin\\Myputs")); // 虽然 MSDN Library 说这里如果  
  18.                                                  // 指定了路径,要用 backslashes (\),  
  19.                                                  // 不要用 forward slashes (/),但  
  20.                                                  // 其实用二者都可以。  
  21.                                                  // 注:如果用 \,要用 \\。  
  22.    
     
  23.     // If the handle is valid, try to get the function address.  
  24.    
     
  25.     if (hinstLib != NULL)   
  26.     {   
  27.         ProcAdd = (MYPROC)GetProcAddress(hinstLib, "myPuts"); // __cdecl   : myPuts  
  28.                                                               // __stdcall : _myPuts@4  
  29.                                                               // __fastcall: @myPuts@4  
  30.    
     
  31.         // If the function address is valid, call the function.  
  32.    
     
  33.         if (NULL != ProcAdd)   
  34.         {  
  35.             fRunTimeLinkSuccess = TRUE;  
  36.             (ProcAdd) (TEXT("Message via DLL function\n"));   
  37.         }  
  38.    
     
  39.         // Free the DLL module.  
  40.    
     
  41.         fFreeResult = FreeLibrary(hinstLib);   
  42.     }   
  43.    
     
  44.     // If unable to call the DLL function, use an alternative.  
  45.    
     
  46.     if (! fRunTimeLinkSuccess)   
  47.         printf("Message via alternative method\n");   
  48. }  

原文:http://blog.csdn.net/g5dsk/article/details/6680698

GetProcAddress 使用注意事项的更多相关文章

  1. 64位内核开发第二讲.内核编程注意事项,以及UNICODE_STRING

    目录 一丶驱动是如何运行的 1.服务注册驱动 二丶Ring3跟Ring0通讯的几种方式 1.IOCTRL_CODE 控制代码的几种IO 2.非控制 缓冲区的三种方式. 三丶Ring3跟Ring0开发区 ...

  2. jQuery UI resizable使用注意事项、实时等比例拉伸及你不知道的技巧

    这篇文章总结的是我在使用resizable插件的过程中,遇到的问题及变通应用的奇思妙想. 一.resizable使用注意事项 以下是我在jsfiddle上写的测试demo:http://jsfiddl ...

  3. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  4. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  5. app开发外包注意事项,2017最新资讯

    我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...

  6. favicon.ioc使用以及注意事项

    1.效果 2.使用引入方法 2.1 注意事项:(把图标命名为favicon.ico,并且放在根目录下,同时使用Link标签,多重保险) 浏览器默认使用根目录下的favicon.ico 图标(如果你并没 ...

  7. ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  8. 【原】Masonry+UIScrollView的使用注意事项

    [原]Masonry+UIScrollView的使用注意事项 本文转载请注明出处 —— polobymulberry-博客园 1.问题描述 我想实现的使用在一个UIScrollView依次添加三个UI ...

  9. 《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。附:网友制作的类库说明(CHM)

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

随机推荐

  1. window下完全删除nodejs

    1.从卸载程序卸载程序和功能. 2.重新启动(或者您可能会从任务管理器中杀死所有与节点相关的进程). 3.寻找这些文件夹并删除它们(及其内容)(如果还有).根据您安装的版本,UAC设置和CPU架构,这 ...

  2. 面向对象设计原则 依赖倒置原则(Dependency Inversion Principle)

    依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现. 简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块 ...

  3. ASP.net 简单分页的实现

    在自己的项目中有一个文章的管理页面需要用到分页, 这种分页方法是在黑马的一个视频中看到的,便用在了自己的项目中. 但是使用控件实在是太丑,虽然我写的也丑....... gridview 控件提供的分页 ...

  4. JMS异步消息机制

    企业消息系统 Java Message Service 是由 Sun Microsystems 开发的,它为 Java 程序提供一种访问 企业消息系统 的方法.在讨论 JMS 之前,我们分来析一下企业 ...

  5. 【洛谷】NOIP提高组模拟赛Day1【组合数学】【贪心+背包】【网络流判断是否满流以及流量方案】

    U41568 Agent1 题目背景 2018年11月17日,中国香港将会迎来一场XM大战,是世界各地的ENLIGHTENED与RESISTANCE开战的地点,某地 的ENLIGHTENED总部也想派 ...

  6. Codeforces Round #355 (Div. 2) C. Vanya and Label 水题

    C. Vanya and Label 题目连接: http://www.codeforces.com/contest/677/problem/C Description While walking d ...

  7. Swift3.0字符串相关操作

    以下有关字符串的常用操作都可直接复制到Xcode中进行验证,如发现错误,请在评论区留言指正! 1.字符串的定义 var str1="hello, swift." //字符串变量 相 ...

  8. Java_JSP自定义标签的开发与应用

    在JSTL提供了四个标签库(核心标签库.国际化标签库.数据库标签库和XML标签库),涉及到了几十个标签.虽然这些标签可以完成比较复杂的工作,但它们仍然无法满足程序中的特殊需求.因此,就需要用户根据自己 ...

  9. [Android] 字体使用dp单位避免设置系统字体大小对排版的影响

    [Android] 字体使用dp单位避免设置系统字体大小对排版的影响 以魄族mx3为例,在设置->显示->字体大小中能够选择字号大小例如以下图: 图1. 魄族mx3 会导致软件在有固定定高 ...

  10. xvcd – The Xilinx Virtual Cable Daemon

    http://debugmo.de/2012/02/xvcd-the-xilinx-virtual-cable-daemon/ I recently discovered an almost undo ...