何时编写动态链接库 [英] When to write Dynamic Linking Libraries

查看:82
本文介绍了何时编写动态链接库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


您能否让我知道为什么应该真正开始编写动态链接库.

性能如何?

:)

Hi,
Can you please let me know as to why one should actually start writing Dynamic Linking Libraries.

How about the performance?

:)

推荐答案

当您放入dll的功能将由多个模块使用时.
您可以将其放在库中,然后将其链接到程序集/可执行文件中,并最终在多个位置包含相同的代码. (多个可执行文件)
最重要的是,如果代码更改了但界面没有更改,则可以更改dll,而不必替换所有使用该dll的代码.
一些库非常聪明,可以让您在dll和lib之间进行选择.例如,MFC提供了这种选择.如果链接,则会得到一个更大的可执行文件,其中包含实际使用的mfc部分;如果使用dll,那么可执行文件会更小.
可重用的代码应该放在库或dll中,或者您始终共享代码并始终编译和链接.
When the functionality you put in your dll is going to be used by more than one module.
You could put it in a library but then it will be linked in your assembly/executable and eventually the same code is contained in multiple places. (multiple executables)
On top of this, if the code changes but the interface does not, you can change a dll without having to replace all the code that makes use of the dll.
Some libraries are very smart and offer you the possibility to choose between a dll and a lib. For instance MFC offers this choice. If you link, you get a bigger executable, containing the part of mfc you actually use, if you use a dll, well your executable will be smaller.
Code that is reusable should be put either in a library or in a dll, or you simply share the code all the time and compile and link it allways.


简短答案:
如果没有必要,请不要使用DLL,因为它总是很麻烦.性能:不能内联导出的DLL函数,因此,如果将非常简单的愚蠢函数放入DLL中,例如数学3D矢量加法(应始终内联),这会大大降低性能.

长答案:
使用DLL作为Philip Stuyck和Kenneth Haugland已描述的内容的补充的充分理由:
-使用DLL,可以减少大型代码库中的链接时间,因为如果您在大型程序中进行某些修改.
-某些程序(例如游戏引擎)即使在调试模式下也必须以合理的速度运行,您可以通过将一些代码拆分为单独的DLL并使用不同的配置编译DLL来达到此目的,仅将调试引擎的那些部分置于调试模式必须调试,其他所有内容都可以在发布模式下进行优化.您必须确保DLL接口不包含在声明和释放模式下declaratino不同的类型(例如,stl容器仅在调试模式下包含某些字段).
-您可能要与用另一种语言编写的另一个程序进行交互.
-您可能需要程序中的DLL接口,因为您希望程序可以通过插件DLL进行扩展.
-有时只有DLL可以执行此操作,例如,仅当钩子函数位于DLL中时,才可以安装全局窗口钩子.
-您可能只想从DLL中释放源文件而没有完整的源代码-您只包含接口标头.

DLL不好是因为:
-与程序中许多模块链接的静态库和模板代码,例如与exe和DLL链接的模板代码,将在所有模块中实例化-因此DLL不仅可以用于共享代码,还可以帮助代码复制,具体取决于在这种情况下!
-我在DLL内部的__declspec(thread)遇到了麻烦,arrrrrggh. (静态线程局部变量)
-DLL通常从它们自己的堆中分配对象(除非您在DLL中提供分配器挂钩).如果将此对象的指针传递给另一个模块(例如exe),并尝试从exe堆中删除该对象,则可能会出现问题-您可以通过要求dll以某种方式删除它来解决此问题.
-在发现问题所在之前,调试/发布模块的混合版本可能会引起奇怪的症状.
-.......可能在这里列出了许多其他原因,因为不幸的是,在很多情况下必须特别处理DLL中的代码.

如果您编写DLL,则是很好的建议:
您的DLL应该只有一个导出的函数,它返回一个接口指针.接口(仅具有纯虚拟方法的类)应由DLL实现,并且应在调用接口getter函数之前的某个时间实例化该类在DLL中.这样,您只需编写一次DLL导出导入内容,以后就可以将其他与DLL接口相关的内容放入接口类中.
好处:更好的接口看起来像纯C ++,没有难看的DLL导入/导出内容,如果DLL是插件接口,那么您可以在可执行文件中轻松地多次实现该接口,以支持内置插件.使跨平台移植和以后的代码合并到单个模块中变得非常容易!另一个好处:您可以轻松地将带有接口的整个库放入静态库,然后可以创建一个非常小的DLL项目,该项目依赖于此静态库,并且只有一个导出函数实例化实现类并返回接口指针. .这样,您只需很少的工作即可拥有静态的lib和DLL版本.

如果要编写插件DLL接口,则可以使用导出的函数名称进行插件版本控制.例如,DLL接口的getter方法可以使用零版本的名称:"GetPluginInterface".更改接口时,可以将导出的DLL函数名称更改为"GetPluginInterface2",依此类推.我喜欢这种方法,因为通过这种方法,您可以通过实现多个接口来编写支持某些较旧版本程序的更高版本的插件DLL-通常,这两个接口内部都有很多通用代码.
Short answer:
Never use DLLs if you don''t have to because its always a trouble. Performance: Exported DLL functions can not be inlined, so if you put very simple stupid functions into a DLL like math 3D vector addition (that should be inlined all the time) - that can degrade performance a lot.

Long answer:
Good reasons to use a DLL as an additon to what Philip Stuyck and Kenneth Haugland already described:
- With DLLs you can reduce link time in a huge codebase because if you modify something in a big program.
- Some programs (like game engines) must run with reasonable speed even in debug mode, you can reach this by splitting some code into separate DLLs and compiling your DLLs with different configs, you put into debug mode only those parts of the engine that you have to debug, everything else runs in release mode with optimization. You must ensure that the DLL interface doesnt contain types whose declaratino differs in debug and release mode (for example stl containers contain some fields only in debug mode).
- You might want to interface with another program that has been written in another language.
- You might want a DLL interface in your program because you want your program to be extendable by plugin DLLs.
- Sometimes only DLLs can do the stuff, for example you can install a global window hook only if the hook function is in a DLL.
- You might want to release your library only in DLL from without full source code - you include just the interface headers.

DLLs are bad because:
- Static libraries and template code that is linked against many modules in your program for example against your exe and DLL will be instantiated in all of your modules - so DLLs can be used not just to share code, but it helps code duplication as well depending on the circumstances!
- I had trouble with __declspec(thread) inside DLLs, arrrrrggh. (static thread local variables)
- DLLs usually allocate their objects from their own heap (unless you provide allocator hooking in the DLL). This can be a problem if you pass a pointer of this object to another module (for example the exe) and you try to delete it there (from the heap of the exe) - you can solve this by asking the dll to delete it somehow.
- debug/release mixed versions of modules othen cause strange symptoms before you find out whats the problem.
- ....... Probably a lot of other reasons could be listed here because code in a DLL must be handled specially in a lot of cases unfortunately.

Good advices if you write a DLL:
Your DLL should have only one exported function that returns an interface pointer. The interface (class with pure virtual methods only) should be implemented by the DLL, and it should instantiate that class inside the DLL sometime before the interface getter function is called. This way you have to write your DLL export import stuff only once and you can put other DLL interface related stuff into the interface class later.
Benefits: Nicer interface that looks pure C++ without ugly DLL import/export stuff, if the DLL is a plugin interface then you can implement that interface easily many times inside your executable as well to support builtin plugins as well. Makes crossplatform porting and a later code merging into a single module quite easy! Another benefit: You can easily put this whole library with the interface into a static library, and then you can create a very small DLL project that depends on this static library and has only one exported function that instantiates the implementation class and returns the interface pointer. This way you have the static lib and DLL version too with minimal work.

If you are writing a plugin DLL interface that you can use the exported function name for plugin versioning. For example the DLL interface getter method can have this name for your zero version: "GetPluginInterface". When you change the interface you can change the exported DLL function name to "GetPluginInterface2" and so on. I like this method because this way you can write later plugin DLLs that support some older versions too of your program by implementing more than one interfaces - usually the two interfaces have a lot of common code inside.


因为有了dll,您可以在需要时将函数加载到内存中,并在不需要时将其踢出内存.
Becouse with a dll you can load the function into memory when you need it, and kick it out of memory when not needed.


这篇关于何时编写动态链接库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆