dll导出命名空间下的c风格函数陷阱
2017-01-11 21:23
232 查看
1、编译阶段,如果不是重载,那么C风格的同名函数与C++风格的同名函数,就会报编译错误。
error C2084: function 'int Test(void)' already has a body。
2、编译期间,编译器会检查命名空间里的函数。如SG::Test();
编译器会检测是否有函数Test()在SG命名空间里。如果没有就会报错。
error C2039: 'Test' : is not a member of 'SG'
3、链接阶段,当命名空间与extern “C”组合在一起时,生成的函数代码其实是C风格的,没有命名空间修饰。
这是因为C风格里函数里没有命名空间这一概念,所以命名空间自动会被链接器忽略。
基于以上的原则,编译器链接器能够识别出基本所有的错误用法。
但是有一种情况,编译器链接器都无法识别。
那就是
DLLA中有命名空间
DLLB中有命名空间SG2::Test()导出函数。
在EXE中调用SG2::Test()。 这个时候,编译链接都是正确的。 但是实际运行的时候,却隐藏着一个隐患。 因为实际生成的汇编代码直接是
和命名空间无关。 那么汇编代码会调用SG1下的还是SG2下的Test呢? 这两个DLL谁先引用进到EXE,先调用谁。
error C2084: function 'int Test(void)' already has a body。
2、编译期间,编译器会检查命名空间里的函数。如SG::Test();
编译器会检测是否有函数Test()在SG命名空间里。如果没有就会报错。
error C2039: 'Test' : is not a member of 'SG'
3、链接阶段,当命名空间与extern “C”组合在一起时,生成的函数代码其实是C风格的,没有命名空间修饰。
这是因为C风格里函数里没有命名空间这一概念,所以命名空间自动会被链接器忽略。
基于以上的原则,编译器链接器能够识别出基本所有的错误用法。
但是有一种情况,编译器链接器都无法识别。
那就是
DLLA中有命名空间
namespace SG1 { extern "C" __declspec(dllexport) int Test(); }
DLLB中有命名空间SG2::Test()导出函数。
namespace SG2 { extern "C" __declspec(dllexport) void Test(); }
在EXE中调用SG2::Test()。 这个时候,编译链接都是正确的。 但是实际运行的时候,却隐藏着一个隐患。 因为实际生成的汇编代码直接是
004EF8FF FF 15 18 1A 78 00 call dword ptr [__imp__Test (781A18h)]
和命名空间无关。 那么汇编代码会调用SG1下的还是SG2下的Test呢? 这两个DLL谁先引用进到EXE,先调用谁。
相关文章推荐
- dll导出命名空间下的c风格函数陷阱
- 关于DLL函数名导出名字命名规则
- VC++导出具有命名空间的函数
- 关于DLL函数名导出名字命名规则的转帖
- c# 命名空间、dll、与函数
- VC++导出具有命名空间的函数
- 调用未知DLL中的导出函数[转]
- 动态加载dll的导出函数的问题
- 在 C# 中动态调用 native dll 的导出函数
- 查看dll的导出函数
- 透过汇编另眼看世界之DLL导出函数调用
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->clone 函数
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->contains 函数
- 调用未知DLL中的导出函数
- 用.DEF文件导出DLL中的函数
- 调用未知DLL中的导出函数
- 透过汇编另眼看世界之DLL导出函数调用
- C#与DLL和COM的混合编程(1)-C#调用C++写的非托管的DLL中导出的函数
- VB调用DLL导出函数出现“Bad DLL call convention”的解决
- 调用未知DLL中的导出函数