|
|
1
25
我发现同时使用__declspec(dllexport)和.def文件在创建可移植DLL时很有用,即可以从用不同编译器或不同编译器设置编译的代码中调用的DLL。 只需在函数声明中添加__declspec(dllexport),就会导致这些函数被DLL“导出”(至少在Windows上),以便可以从DLL外部调用它们。 但是,在构建中添加一个列出所有导出函数的.def文件,可以阻止Microsoft编译器(例如)在导出函数名中添加前导下划线和尾随参数宽度信息(至少在与__stdcall指令结合使用时,这对可移植性也很有用)。例如,函数声明
最终可能会以“_foo@4“如果你不小心调用约定和.def文件的用法。 在运行时显式加载和挂接到DLL时,在符号表中保持导出的函数名没有这种名称装饰非常方便。也就是说,要在运行时获取指向上述函数foo()的指针(假设它已导出),理想情况下只需调用:
当然,还要进行一些适当的错误案例检查! 在构建DLL时,在函数声明中使用.def文件加上__stdcall、__declspec(dllexport)和extern“C”将确保上述客户端代码适用于各种编译器和编译器设置。 |
|
|
2
21
我的理解是,.def文件提供了__declspec(dllexport)语法的替代方案,其额外好处是能够显式指定导出函数的序号。如果您仅按序号导出某些函数,这可能会很有用,因为这不会显示有关函数本身的太多信息(例如:许多操作系统内部DLL的导出函数仅按序号)。 请参阅 reference page . 请注意,.def文件中的名称必须与二进制文件中的姓名匹配。因此,如果你用C或C++加上'extern“C”{…}',名字就不会被篡改;否则,您必须为用于生成DLL的特定版本的编译器使用正确的错误名称。__declspec()函数会自动完成这一切。 |
|
|
3
12
对于那些仍然感兴趣的人。..为了能够链接到dll和def文件,您还需要一个lib文件。在windows中,可以使用“LIB”工具从def中进行此操作。请参阅下面的命令行方式示例。
希望这能帮助别人。 |
|
|
4
4
我没有太多使用DLL,但我的理解是,对于导出的C++函数,你应该使用“__declspec(dllexport)”,而对于导出的C函数,你应当编写.def文件。这可能是因为C++函数支持重载,但C函数不支持。 |
|
|
5
3
.DEF文件在16位窗口中更为常见,它们通常是指定应导出哪些符号的唯一方法。 此外,它们还提供了一种按序号(@1、@2等)而不是按名称指定导出的方法。当性能非常重要时,例如在视频驱动程序中,会使用这种查找符号的方法。 |
|
|
6
3
我的理解是,.def文件实际上并没有指定需要导出哪些所有api。它只包含导出的api及其序号。如果你想实际导出一个特定的api,你需要在api的定义中指定__declspec(dllexport),并在声明中指定__eclspec(dllimport)。 def文件的优点是,它可以帮助您保持与已经实现的dll的backword兼容性。即它维护api的序号。假设你在dll中添加了一个新的api,那么链接器会查看你的.def文件,为ne wapi生成序号,这样旧api的序号就不会改变。 因此,如果客户端代码使用最新的dll,它不会破坏现有的api。 |
|
|
MaPo · Linux,设置锁定ICMP_过滤器选项 1 年前 |
|
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 1 年前 |
|
|
Bobby · 复合字面值总是左值吗? 1 年前 |
|
9-Pin · C: 嵌套结构的堆栈内存分配 1 年前 |