刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都“乱码”了。

导出过程如下:

新建一个Win32项目:

新建的解决方案里有几个导出的示例:

// 下列 ifdef 块是创建使从 DLL 导出更简单的// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLLEXPORT_EXPORTS// 符号编译的。在使用此 DLL 的// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将// DLLEXPORT_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的// 符号视为是被导出的。#ifdef DLLEXPORT_EXPORTS#define DLLEXPORT_API __declspec(dllexport)#else#define DLLEXPORT_API __declspec(dllimport)#endif// 此类是从 dllExport.dll 导出的class DLLEXPORT_API CdllExport {public:    CdllExport(void);    // TODO: 在此添加您的方法。};extern DLLEXPORT_API int ndllExport;DLLEXPORT_API int fndllExport(void);

于是我什么都不做,直接生成,并且在C#里导入看看能否调用,嗯……错误来了:

找不到入口点?难道是没导出么?我们用“Dependency Walker”来看看:

Oh, shit, WTF is this? 导出是导出了,不过怎么都乱码了?

右键选择“Undecorate C++ Functions”之后才出现了真面目:

不过我们的目的是要在C#中使用,而不是用眼睛在 Dependency 里面看啊!嗯,既然入口点的名字都变了,要不我们在 C# 中手动指定入口点试试?

不错,成功了,我们终于可以使用 C++ dll里导出的函数了。

不过,这些乱码到底是什么东西?百度一下很轻松地找到了答案:

DLL(动态库)导出函数名乱码含义  
C++编译时函数名修饰约定规则:    
  __stdcall调用约定:    
  1、以"?"标识函数名的开始,后跟函数名;   
  2、函数名后面以"@@YG"标识参数表的开始,后跟参数表;  
  3、参数表以代号表示:    
  X--void 
  D--char 
  E--unsigned char 
  F--short 
  H--int 
  I--unsigned int 
  J--long 
  K--unsigned long 
  M--float 
  N--double 
  _N--bool 
  ....    
  PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复;    
  4、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;    
  5、参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。    
  其格式为"?functionname@@YG*****@Z"或"?functionname@@YG*XZ",例如    
                      int Test1(char *var1, unsigned long)-----?Test1@@YGHPADK@Z

void Test2()-----"?Test2@@YGXXZ" 
  __cdecl调用约定:    
  规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YA"。    
  __fastcall调用约定:    
  规则同上面的_stdcall调用约定,只是参数表的开始标识由上面的"@@YG"变为"@@YI"。

如果要用DEF文件输出一个"C++"类,则把要输出的数据和成员的修饰名都写入.def模块定义文件    
  所以...   通过def文件来导出C++类是很麻烦的,并且这个修饰名是不可避免的

虽然有约定的含义,但这也真够麻烦的!我不禁想,我们之前导入 User32.dll,Shell32.dll 等等这些动态库的函数的时候,那些EntryPoint没见这么麻烦啊,怎么回事?还是万能的百度……“在到处函数之前加上“extern "C"”就行了!”,我们来试试:

// 下列 ifdef 块是创建使从 DLL 导出更简单的// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLLEXPORT_EXPORTS// 符号编译的。在使用此 DLL 的// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将// DLLEXPORT_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的// 符号视为是被导出的。#ifdef DLLEXPORT_EXPORTS#define DLLEXPORT_API __declspec(dllexport)#else#define DLLEXPORT_API __declspec(dllimport)#endif// 此类是从 dllExport.dll 导出的class DLLEXPORT_API CdllExport {public:    CdllExport(void);    // TODO: 在此添加您的方法。};extern "C" DLLEXPORT_API int ndllExport;extern "C" DLLEXPORT_API int fndllExport(void);

注意和之前对比,最后两行有变化。编译生成,运行 C# 项目:

没有指定 EntryPoint 了,成功!

C++ 动态库导出函数名乱码及解决相关推荐

  1. C++ 动态库导出函数名“乱码”及解决

    刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...

  2. linux nm工具 查看静动态库导出函数

    查看动态导出函数 方法一 nm -D  **.so 但这样能看到所有的导出,乱七八糟的很多,筛选用: nm **.so | grep XX 方法二 objdump -tT **.so 查看静态导出函数 ...

  3. linux查看动态库导出的符号,Linux下控制动态库导出

    在Linux中动态库的确给程序带来了良好的扩充性,并减少了内存的使用量,但这是有代价的.例如: #include Int main(int argc, char *argv[]) { Printf(& ...

  4. 【Android 逆向】函数拦截实例 ( 函数拦截流程 | ① 定位动态库及函数位置 )

    文章目录 一.函数拦截流程 二.定位动态库及函数位置 一.函数拦截流程 函数拦截流程 : 定位动态库及函数位置 : 获取该动态库在内存中的位置 , 以便于 查找函数位置 ; 插桩 : 在函数的入口处插 ...

  5. Android-JNI开发系列《一》-动态库的函数注册

    JNI-动态库的函数注册 时光荏苒,距离上次的文章已经3年多了.那这3年干啥了呢?平凡生活,在人间凑数. 来吧,展示!show me you code 在Linux平台下so库分为动态库和静态库.表现 ...

  6. 不用工具查看dll的导出函数名的方法!

    用记事本打开dll文件,用dll的文件名(如:mydll.dll)查找,文件名后面就是dll的导出函数名了.

  7. php自定义函数出现乱码,php的imagettftext 函数出现乱码的解决方法

    php的imagettftext 函数出现乱码的解决方法:今天遇到一个问题,就是往图片上打文字水印,当是汉字的时候出现了乱码,是英文时候并没有出现乱码. 查资料后最终找到两种解决方案,分别如下: 1. ...

  8. php excel中文名称乱码,phpexcel导出中文文件名乱码的解决办法

    使用phpexcel类库导出excel文件,文件名为中文时,在chrome浏览器下导出正常,在IE内核浏览器下导出文件名显示乱码,解决办法就是通过iconv函数转换编码,从utf-8转为gb2312, ...

  9. php 中文 decode_PHP中json_decode函数中文乱码如何解决?

    PHP中json_decode函数中文乱码如何解决? PHP中json_decode函数中文乱码解决方法:1.使用函数"urldecode()"将数据进行解码,解码后再进行JSON ...

最新文章

  1. js 数据类型和转化
  2. 我的centos上安装 jdk+apache+tomcat+tomcatconnector+myql 安装道路
  3. 2021年度总结——做好事不留名·CSDN中的【雷锋】
  4. php snoopy视频教程,php的Snoopy类
  5. Java基础——Java NIO详解(二)
  6. 让运维更高效:关于ECS系统事件
  7. U盘安装centos 7 提示 “Warning: /dev/root does not exist, could not boot” 解决办法
  8. Reflector.exe + ilDasm.exe + ilasm.exe 破解DundasWebChart(VS2005) 5.5 成功
  9. mysql存储过程switch_Mysql存储过程从0开始(上)
  10. 工业控制网络常用通信协议
  11. Excel小技巧,隔行变色,多行变色
  12. 转文:华为鸿蒙操作系统全景解构
  13. 每日一句: I don't think it's necessary for you to give up
  14. 【模拟】相似度 (similar.pas/c/cpp)
  15. kotlin android 开源,一款纯Kotlin编写的开源安卓应用 Smile
  16. python简单程序实例-python简单项目实例
  17. 我为什么不是清华的学生
  18. 游戏大厅 从基础开始(4)-通过L2X用配置文件反射组装程序(VB only)
  19. Python项目实战:使用PySpark对大数据进行分析
  20. 离散数学 第二章-一阶逻辑

热门文章

  1. 鸿蒙开发者beta活动,华为官宣:12月16日举行鸿蒙2.0手机开发者Beta活动
  2. 苹果一项“杀手锏”过审,“智能穿戴+大健康”领域风云再起
  3. 如何掌握高效学习方法,提高学习效率?
  4. 【算力网络】算力网络的技术创新——算力基础设施关键技术
  5. python画旺仔代码_Python基础3
  6. jsp汽车租赁系统ssh
  7. Vue 移动端 previewer实现图片放大预览
  8. 计算机专业对身体伤害大,电脑对人体的三大伤害
  9. 推迟势的简单推导,希尔伯特空间引入以及分离变量法
  10. PCIe 均衡技术介绍(电气物理篇)