通过GetProcAddress函数动态调用dll中的函数,是否必须通过extern "C"声明导出函数? [已结贴,结贴人:darongtou]
如题,网上搜了N多资料,一直找不到确定的答案,目前我的答案是“”。 
晚上因为一个程序,好好研究了一下。 
很多资料上都只是说明“如果没有 extern "C" 修饰,输出函数仅仅能从 C++ 代码中调用。” 
却并没有明确这个调用是通过显式调用还是隐式调用,我也一直没有看到过有代码是通过显示调用没有 extern "C" 修饰的导出函数。 
MSDN上也只是说 
The   spelling   and   case   of   the   function   name   pointed   to   by   lpProcName   must   be   identical   to   that   in   the   EXPORTS   statement   of   the   source   DLL's   module-definition   (.DEF)   file.   The   exported   names   of   Win32   API   functions   may   differ   from   the   names   you   use   when   calling   these   functions   in   your   code.   
下面再从理论方面进行一些分析: 
GetProcAddress函数声明是: 
FARPROC   GetProcAddress( 
    HMODULE   hModule,         //   handle   to   DLL   module 
    LPCSTR   lpProcName       //   name   of   function 
); 
C++是支持函数重载的,也就是说允许多个不同的函数可以有同样的函数名,如果不通过extern "C"修饰,就可以输出相同的函数名。 
这样,就和GetProcAddress函数声明不一致了,所以推断不能动态调用没有extern "C"修饰的导出函数,因为GetProcAddress函数是通过函数名来唯一确定被调用函数的地址的。 

欢迎大家讨论!

第1个回答

显示调用必须使用extern "C"修饰符。隐式调用可以使用任何类型,但只有C++能调用没有extern "C"修饰的导出函数。 
GetProcAddress是一种通用的获取函数入口点的API,能被任何语言调用,所以限制一定比较多,比如它的参数一定是一个ANSI串(操作系统并未提供UNICODE版本)。
第2个回答
我的理解是这样的:GetProcAddress实际上跟你直接调用myfunc()一样,都是查询Export表来得到函数地址再去调用,因此你修饰符不对就会造成找不到entry,是不行的。当然我没试过,没有完全的把握。
第3个回答
C函数和C++函数的名称是不一样的,可以使用工具来查看,比如Dependency   Walker。如果你想试验,可以根据工具看到的名称来调用GetProcAddress试试
第4个回答
主要是就是名字的问题 
有两种例外情况可以不加extern "C": 
1。如果不是用C++编译器而是用C编译DLL,名字不会变,可以不加extern "C" 
2。如果DLL的使用者知道是用C++编译器编译DLL,不加extern "C"也可以,因为他知道名字改变的规则。调用GetProcAddress,把函数名字改了就是了

第5个回答

C++编译器和C编译器编译后生成的函数名不一样。 
GetProcAddress认为是cdecl的函数,而 
编译DLL的是VC++,所以要加一个extern "C"的修饰符 
指明以cdecl的方式生成函数。
第6个回答
发现不用加extern "C"也是可以的,只要在调用端用修饰过的函数名即可,不能用原函数名。 
例子关键代码如下: 
---------------------------- 
DLL部分: 
//   This   is   an   example   of   an   exported   function. 
DLL1_API   int   __cdecl   fnDll1(void) 
return   42; 
输出的修饰函数名为?fnDll1@@YAHXZ 
DLL1_API   int   __cdecl   fnDll1(int   a) 
return   42+a; 
输出的修饰函数名为?fnDll1@@YAHH@Z 
----------------------------- 
EXE部分: 
HINSTANCE   hModule   =   LoadLibrary("dll1.dll"); 
ASSERT(hModule); 
typedef   int   (*fnDll1)(); 
fnDll1   pfnDll1   =   NULL; 
//VERIFY(pfnDll1   =   (fnDll1)::GetProcAddress(hModule,   "fnDll1")); 
VERIFY(pfnDll1   =   (fnDll1)::GetProcAddress(hModule,   "?fnDll1@@YAHXZ")); 
ASSERT(pfnDll1()   ==   42); 
typedef   int   (*fnDll2)(int); 
fnDll2   pfnDll2   =   NULL; 
VERIFY(pfnDll2   =   (fnDll2)::GetProcAddress(hModule,   "?fnDll1@@YAHH@Z")); 
ASSERT(pfnDll2(3)   ==   45); 
--------------------------- 
这事暂时可以告一段落了,实验还是最有力的证明。

转载于:https://www.cnblogs.com/whiteyun/archive/2011/07/22/2113560.html

通过GetProcAddress函数动态调用dll中地函数,是否必须通过extern C声明导出函数?(转)...相关推荐

  1. GetProcAddress()函数动态调用DLL中的函数,是否必须通过extern C声明导出函数?

    GetProcAddress()函数动态调用DLL中的函数,是否必须通过extern C声明导出函数? 通过GetProcAddress函数动态调用dll中的函数,是否必须通过extern " ...

  2. Qt调用dll中的功能函数

    http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810239.html 声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll ...

  3. 【转】Qt调用dll中的功能函数

    DLL 优点 ------------------------------------- 1.扩展了应用程序的特性: 2.可以用许多种编程语言来编写: 3.简化了软件项目的管理: 4.有助于节省内存: ...

  4. python如何调用dll库中的函数_Python调用dll库接口-ctypes方法

    背景 最近需要用python写个脚本程序(win10 环境),需要调用现成的dll库完成这项任务,对于一直在Linux平台上开发程序的本人来说,从没有过使用dll的经历(不得不说还是so大法好),遇到 ...

  5. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法--将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  6. 如何调用 DLL 中的函数

     如何调用 DLL 中的函数 在 DLL工程中的 cpp中函数定义如下: extern "C" _declspec (dllexport ) int add(int a, ch ...

  7. Delphi中动态调用DLL的方法

    Delphi中动态调用dll的方法如下: function CallFunc(dllname, funcname: string; const param: array of const): DWOR ...

  8. 如何调用DLL中的函数

    如何调用 DLL 中的函数 在 DLL工程中的 cpp中函数定义如下: extern "C" _declspec (dllexport ) int add(int a, char ...

  9. 天马行空W:在C++中调用DLL中的函数

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

最新文章

  1. 8 - 9 template两大功能 : simple_tag、模板继承
  2. MySQL · 性能优化· CloudDBA SQL优化建议之统计信息获取
  3. 找新房子需要考虑的因素
  4. occ-backend-base-url 的相关代码,如何调试?
  5. springboot 整合 kafka demo 顺便看一下源码
  6. Kubernetes 日志查询分析实践
  7. android高德地图绘制多边形_Android安卓高德地图实现多边形绘制与编辑
  8. cloudera cdh5.13.0 vmware 快速安装
  9. java 一次CPU占用过高问题的排查及解决,java基础面试笔试题
  10. 全系标配!Redmi K40系列锁定三星E4材质OLED屏幕
  11. 这就是程序员被大厂偏爱的实力!
  12. sql语句distinct_带DISTINCT子句SQL SELECT语句
  13. java设计模式-Observe
  14. 使用python中正则表达式匹配linux ifconifg命令中的具体信息
  15. python 线程-threding示例使用
  16. 问卷星图片自动提取小程序
  17. Excel数据可视化表盘模板
  18. 十大编程语言的优劣对比简述
  19. 微信小程序 云开发 图片内容安全 珊瑚图片内容安全 api
  20. 【暮色天】行情反复 愈挫愈勇(1.15)

热门文章

  1. 4个月高效备考信息系统项目管理师经验分享【57,49,49】
  2. 信息系统项目管理师学习方法
  3. grep查询不到中文 或 Binary file xx matches
  4. CI/CD 最佳实践的基本原则
  5. CentOS7中怎样修改主机名和hosts文件(配置IP和主机名的对应管理)
  6. Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口
  7. Python中通过MyQR生成gif动图二维码
  8. Atom JS 代码智能提示补全
  9. 国内常用的学习flutter地址
  10. JDBC连接时所犯错误1.字符集设置不合适2.连接MySQL8.0社区版时时区不一致3..包名不能以Java.命名4.驱动被弃用