两个程序同时调用一个DLL可以吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两个程序同时调用一个DLL可以吗相关的知识,希望对你有一定的参考价值。
TY
当然可以了,DLL就是用来供多个程序共享代码的。 参考技术A DLL 有一个特殊的入口点(DllMain 函数),它在附加和分离进程和线程时运行。此行为允许根据需要创建和销毁数据结构。文件扩展名为 .ocx、.cpl 和 .drv 的文件类型也是 DLL,尽管文件扩展名已改变。在 Windows 2.x 和 Windows 3.x 中,每个 DLL 都只有一个数据段实例,而不管有多少应用程序。在 Windows 32 中,可以将 DLL 标记为共享以导致相同的行为。但是,每个进程的默认设置是拥有 DLL 数据的专用副本。您可以通过创建 DLL 实现以下目的: ? 将程序划分为可按需加载的单独模块。
? 存储特定于语言或特定于区域的资源。
? 使您自己的应用程序能够使用核心代码库。
? 生成进程内 COM 对象或 ActiveX 控件 (OCX)。
? 将 OLE 对象用作进程内 DLL。这一用法可改进 OLE 链接的性能。
? 使用控制面板扩展或使用某些类型的驱动程序。
要生成 DLL,请使用 DllMain 函数(而不是程序文件)替换 WinMain 函数。
要在 Win16 中导出函数,请将 FAR EXPORT 添加到所有导出的 DLL 函数(在 Win32 中不要求这样做)。许多 32 位编译器提供了函数声明符,例如 __declspec(dllexport) 和 __declspec(dllimport)。这些函数声明符出现在函数声明之前以代替调用。不过,定义必须仅指定 dllexport 属性。
1. 共享代码、资源和数据
使用DLL的主要目的就是为了共享代码,DLL的代码可以被所有的Windows应用程序共享。
2. 隐藏实现的细节
DLL中的方法可以被应用程序访问,而应用程序并不知道这些方法的细节。
3. 拓展开发工具的功能
由于DLL是与语言无关的,因此可以创建一个DLL,被C++、VB或任何支持动态链接库的语言调用。这样如果一种语言存在不足,就可以通过访问另一种语言创建的DLL来弥补。
两个线程可以调用同一个DLL中的两个函数吗?
【中文标题】两个线程可以调用同一个DLL中的两个函数吗?【英文标题】:Can two functions in same DLL be called by two threads? 【发布时间】:2014-08-27 22:57:23 【问题描述】:我用Visual C++ 2008写了一个DLL MyDLL.dll,如下:
(1) MFC 静态链接 (2) 使用多线程运行库。
在DLL中,这是两个导出函数共享的全局数据m_Data,如下:
ULONGLONG WINAPI MyFun1(LPVOID *lpCallbackFun1)
...
Write m_Data(using Critical section to protect)
…
return xxx;
ULONGLONG WINAPI MyFun2(LPVOID *lpCallbackFun2)
...
Suspend MyThread1 to prevent conflict.
Read m_Data(using Critical section to protect)
Resume MyThread1.
…
return xxx;
在我的主应用程序中,它会先调用LoadLibrary来加载MyDLL.dll,然后获取MyFun1和MyFun2的地址,然后做如下事情:
(1) 启动一个新线程MyThread1,它会调用MyFun1来做一个耗时的任务。 (2) 启动一个新线程MyThread2,会多次调用MyFun2,如下:
for (nIndex = 0; nIndex = 20; nIndex)
nResult2 = MyFun2(lpCallbackFun2);
NextStatement2;
虽然 MyThread1 和 MyThread2 使用临界区来保护共享数据 m_Data,但我仍然会在访问共享数据之前暂停 MyThread1,以防止任何可能的冲突。
问题是:
(1) MyFun2第一次调用时,一切正常,MyFun2(即nResult2)的返回值为1,符合预期。 (2) MyFun2第二、三、四次invoke时,MyFun2中的操作执行成功,但MyFun2(即nResult2)的返回值是随机值,而不是期望值1。我尝试使用Debug来跟踪到 MyFun2,并确认最后一个 return 语句只是返回一个值 1,但是调用者在检查 nResult2 时将收到一个随机值而不是 1。 (3) MyFun2 第四次调用后返回 MyFun2 后面的下一条语句,无论下一条语句是什么,我总是会得到“buffer overrun detected”的错误。
我认为这看起来像是堆栈损坏,因此请尝试进行一些测试:
-
我确认编译器中的 /GS(堆栈安全检查)功能已开启。
如果在 MyThread1 中的 MyFun1 完成后调用 MyFun2,则一切正常。
在调试模式下,MyFun2 中读取共享数据 m_Data 的代码行不会导致任何错误或异常。 MyFun1 中写入共享数据的代码行也不会。
那么,如何解决这个问题
谢谢!
【问题讨论】:
我不知道您的问题,可能是您未显示的大型代码中的一个无关问题。但是请不要暂停其他线程,那将导致灾难! 临界区将在需要时停止和恢复线程,前提是它们被正确使用。 你使用SuspendThread()
函数吗?
问题解决了,我获取到函数地址后,缺少WINAPI修饰符。
【参考方案1】:
我想在这一行
Suspend MyThread1 to prevent conflict.
您正在使用SuspendThread() 函数。这就是它的文档所说的:
这个函数主要是为调试器设计的。 它不适用于线程同步。如果调用线程尝试获取挂起线程拥有的同步对象,则在拥有同步对象(例如互斥锁或临界区)的线程上调用 SuspendThread 可能会导致死锁。为避免这种情况,应用程序中不是调试器的线程应向其他线程发出信号以暂停自身。目标线程必须设计为监视此信号并做出适当的响应。
所以,简而言之:不要使用它。关键部分和其他同步对象可以正常工作。
【讨论】:
【参考方案2】:永远不要使用 SupsendThread!!!绝不! SuspendThread 仅用于调试目的。
原因很简单。你不知道你在哪里暂停线程。当线程阻塞您要使用的资源时,它可能是及时的。还有一堆 CRT 函数使用线程同步。 只需使用关键的 sectins 或 mutexes。
只需在此处查看简单示例:http://blog.kalmbachnet.de/?postid=6 和此处 http://blog.kalmbachnet.de/?postid=16
【讨论】:
【参考方案3】:由于这是一个 windows 程序,您可以在读取或写入共享数据时使用基于 windows 的互斥锁或信号量和 WaitForSingleObject。
【讨论】:
以上是关于两个程序同时调用一个DLL可以吗的主要内容,如果未能解决你的问题,请参考以下文章
我可以从 4.6.1 Web 应用程序调用 .NET 4.7.1 DLL 吗?