IntervalZero RTX64 4.x 帮助文档

⌘K
  1. 主页
  2. 文档
  3. IntervalZero RTX64 4.x 帮助...
  4. RTSS 实时子系统
  5. 实时进程和动态链接库 (DLL)

实时进程和动态链接库 (DLL)

RTX64 支持以下类型的进程和库:


实时进程(Real-time Processes)

实时进程是在 RTX64 子系统内运行的程序,通常称为 RTSS 进程。RTSS 进程可以由一个或多个线程组成,这些线程可以在进程或线程关联掩码内的任何 RTSS 处理器上运行。实时进程使用 .RTSS 扩展名,可以使用 C 或 C++ 编写。


代理进程(Proxy Processes)

代理进程是实时子系统(RTSS)内运行的程序。代理进程可以由运行在第一个 RTSS 进程上的一个或多个线程组成。这些进程位于子系统内部,代表着与实时线程和对象交互的 Windows 进程和线程。


实时动态链接库(RTDLL)

实时动态链接库 (RTDLL:Real-Time Dynamic Link Library) 是一个包含了函数和数据的模块,可以被 RTSS 进程或另一个 RTDLL 调用。RTDLL 在进程加载时被隐式或显式加载。

隐式加载是通过链接到一个(需要在 RTSS 进程中使用的)RTDLL 导出库完成的。使用这种方式,RTSS 进程在构建过程中,就可以解析所有通过 RTDLL 导出的函数。RTSS 进程加载时,加载程序会触发 RTDLL 的加载,以便 RTSS 进程使用这些导出函数。

显式加载不需要链接导出库。而是通过调用 LoadLibraryGetProcAddressFreeLibrary 标准库完成。

实时动态库使用 .RTDLL 扩展名,使用 C 或 C++ 编写。

注意:RTDLL 二进制文件仅在 RTSS 环境中受支持。如果要从 Win32 程序调用,必须将源代码构建为可在 Windows 进程中使用的 DLL。

RTDLL 在 RTSS 加载时加载,且不能在多个 RTSS 进程之间共享。如果两个 RTSS 进程需要调用相同的 RTDLL,则每个 RTSS 进程必须在内存中拥有自己的 RTDLL 镜像。因此,RTDLL 镜像中的全局变量对于调用它们的 RTSS 进程来说是私有的。

注意:不支持在同一 RTDLL 文件中加载的 RTSS 进程之间共享 RTDLL 数据。

与 Windows DLL 类似,当 RTDLL 首次加载到 RTSS 进程中时,RTX64 加载程序会调用 RTDLL 的 DllMain 函数,并向其 fdwReason 参数传递 DLL_PROCESS_ATTACH 值。该操作仅在 RTDLL 的首次加载到 RTSS 进程时进行。

  • 在隐式加载中,进程的主线程使用 DLL_PROCESS_ATTACH 调用 DLLMain。如果 DLLMain 返回 FALSE,则加载进程的 CreateProcess 调用将失败;
  • 在显式加载中,Loadlibrary 线程使用 DLL_PROCESS_ATTACH 调用 DLLMain。如果 DllMain 返回 FALSE,RTDLL 的 LoadLibrary 调用将失败;

当 RTDLL 从 RTSS 进程中卸载时,RTX64 加载程序会调用 RTDLL 的 DllMain 函数,并向其 fdwReason 参数传递 DLL_PROCESS_DETACH 值。执行 DllMain 函数代码的线程上下文取决于进程终止情况。

  • 在隐式卸载中,RTDLL 由于进程退出而被卸载,DllMain 函数代码由RTX64 内部系统线程 RtssServer 执行;
  • 在显式卸载中,RTDLL 被卸载是因为进程中的一个线程调用了FreeLibrary。DllMain 函数代码由调用 FreeLibrary 的线程执行;

与 Windows 不同,RTSS 不会在线程创建时使用参数 DLL_THREAD_ATTACH 调用 DLLMain,也不会在线程退出时使用参数 DLL_THREAD_DETACH 调用 DLLMain。

注意:RTX64 不支持基于序数绑定的 RTDLL。


DLL_PROCESS_DETACH 和隐式链接

当使用隐式链接时,在进程清理阶段,内部系统线程会调用 DLL_PROCESS_DETACH。隐式 DLL 分离发生在 ExitProcess 结束时。用户代码不应在 DLL_PROCESS_DETACH 期间执行任何 API 调用。

调试必须使用 RtPrintf 完成,不允许调用 printf。断点也是不允许的。

重要提示:不遵守这些限制可能会导致 RTX64 变得不稳定。