【问题标题】:How to implement a stateful dll in c++如何在 C++ 中实现有状态的 dll
【发布时间】:2020-03-06 07:15:44
【问题描述】:

(抱歉,无法发布代码)

在实现 dll 时,无状态具有优势。一个例子是视频分析,其结果取决于最近的帧。 dll 的操作有一个状态(=最近的帧)。但是,此状态是基于内存的,因此它可以由调用者拥有,并且 dll 保持无状态。

但是,您不能总是使 dll 无状态。考虑一个依赖于另一个具有状态的第三方 dll 的 dll。该状态可能基于 GPU、线程和通信资源。您不想将调用者暴露给其他第三方 dll,因此您需要(从您的 dll 中)维护状态。

如何在 dll 中使用 c++ 最优雅、最有效地实现这一点?

我当前的实现有一个名为DllContext 的类。 DllContext 只被实例化一次,永远只有一个对象。有一个DllContext* 类型的静态指针,它将在其生命周期内保存该对象。这里的静态意味着范围:它定义在任何函数体之外,而不是任何类的一部分。它只能从定义 3 个 dll 入口点的最小文件中访​​问:

dllinit(): 使用new创建对象

dlldeInit(): 使用delete删除对象

dlldoWork(): 调用DllContext对象对应的doWork()

我不喜欢这个解决方案。我会说它不是单例解决方案,因为该对象只能从一个最小文件中访​​问。但是还是很丑,有什么建议吗?

【问题讨论】:

  • 典型的 C 解决方案是创建一个“初始化”函数,该函数返回指向包含所需状态的 opaque data type 的指针。然后,这个结构将被传递给 DLL 中的函数。 C++ 解决方案是让“初始化”返回一个类的实例,可能使用pimpl idiom
  • @Someprogrammerdude,这是我对基于内存的状态所做的方法。这对我来说很有意义,调用者获得了所有权(即使不允许自己修改状态)。当状态是非记忆时,这在我看来是危险的。它意味着所有权,这是不正确的。还是?
  • “状态是非记忆”是什么意思?如果你设计和实现它,没有什么能阻止你多次使用“初始化”,除非底层“状态”是用于非共享资源(例如显卡或类似的独特设备)。但即便如此,您也可以实现自己的内部共享(例如互斥锁或原子原语或类似的)。
  • @Someprogrammerdude,我想你在评论中回答了你自己的问题,我在问题中特别提到了 GPU 和网络。但是,我很有可能误解了一些基本的东西,所以请详细说明。无论如何,谢谢

标签: c++ windows dll stateless stateful


【解决方案1】:

您没有太多选择。在第一次无状态调用时调用 init。使用小型包装静态对象,而不是裸 DllContext 指针,以便能够在其析构函数中调用 deInit。或者甚至不要打扰deInitWhy cleaning the house to be demolished? 除非确实有不是“防止内存泄漏”的原因。

【讨论】:

  • 感谢您的回答。我是否理解您认为当前的解决方案是可以接受的,使用包装静态对象(这确实是一种改进,尽管很小)?关于打扫房子。可能有与内存(或线程)无关的原因。想到 GPU 和网络资源。
  • @Stefan 如果进程在没有释放这些资源的情况下结束,您是否会知道不想要的后果?如果答案是否定的,那么您不应该为释放它们而烦恼。但是,是的,您当前的解决方案很好。
  • 操作系统与 NVidia 驱动程序相结合可能会及时释放 GPU 资源……但不如推荐的方式稳定,而且速度也不快。释放这些资源似乎更好,即使这意味着阻止调用,这样它就可以在同一应用程序中免费使用......可能由其他模块使用。
  • 将坚持接受和支持,等待有人给出更好的答案。我真的希望有一个更好的答案(我想我们都希望如此:))。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-10
  • 2022-06-15
相关资源
最近更新 更多