两个程序同时调用一个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可以吗的主要内容,如果未能解决你的问题,请参考以下文章

两个线程可以调用同一个DLL中的两个函数吗?

易语言怎么调用DLL文件?

我可以从 4.6.1 Web 应用程序调用 .NET 4.7.1 DLL 吗?

EXE执行文件如何调用DLL?

vb.net把dll放到程序的Resources资源里面,能直接调用Resources里面的dll吗?

静态库 动态库 调用