我正在将一些函数移动到一个共享的DLL (我希望有一些函数被称为Windows钩子)。
实际的函数当前在一个unit中,它恰好有一些initialization和一些finalization代码。
我最初想做一个从unit到library的直接转换。所以我把initialization代码移到了主begin和end.之间。但是后来我意识到我没有地方可以移动finalization代码。相反,我应该创建并注册一个特殊的DLL入口点。
我的问题是。我是否可以将所有函数以及initialization和finalization代码保留在unit中,而只创建一个uses单元的library存根?这个finalization会被调用吗?
发布于 2011-01-12 02:50:38
当DLL第一次加载到进程中时,DLL中单元的初始化部分中的代码将运行。当从进程中卸载DLL时,终结节将触发。
尤金说得对,你可以使用DLLProc进行更细粒度的控制,但这通常只适用于每个线程的资源,例如线程本地存储。
我要指出的是,在DLLMain期间可以做的事情有严重的限制,这最终是这些初始化/结束部分在库中产生的地方。MSDN文档基本上是说您可以做一些事情,但没有可接受的行为列表。它最接近的说法是你可以在kernel32中调用函数。否则,所有的赌注都会被取消!
网上有很多文章描述了这个问题,但除了我上面链接的关于DLLMain的MSDN主题之外,我建议您阅读微软的Best Practices for Creating DLLs。
MSDN提供的有用建议是,该库可以强制其用户在使用DLL之前调用初始化函数。一旦完成DLL,就会调用相应的终结化函数。comctl32.dll的使用采用了这个习惯用法,参见InitCommonControlsEx。
在我自己的代码中,我更喜欢另一种方法。我的所有单元的初始化部分都注册了初始化和结束方法。然后,在第一次从我的库中调用任何导出的函数时,初始化方法将按照它们注册的顺序运行。这对我来说不是一个问题,因为我已经控制了我的库的所有入口点/出口点。
我知道这比你要求的要多,但是你可能会发现避免一些很难调试的问题是有帮助的。
发布于 2011-01-12 02:13:01
如果一个单元是一个程序,如果它是一个库,那么它的初始化将被调用。
对于最终结果也是如此。
所以,是的,您可以让单元保持原样,并导出所需的功能。
发布于 2011-01-12 02:14:43
我建议您实现一个DLLMain,并通过为每种情况调用专用的过程/函数来处理不同的情况(进程附加、线程附加等)。然后,如果您需要从DLL切换到单元,则可以从初始化和终止调用所需的过程/函数。原因是,当DLL附加到线程或从线程分离时,您可能需要一些细粒度的控制(当您设置系统范围的钩子时,就会发生这种情况)。
https://stackoverflow.com/questions/4661015
复制相似问题