如果对象定义在 DLL/Lib 中,是否可以在客户端实例化对象?
Is it possible to instantiate an object in a client if it's defined in a DLL/Lib?
我想不出更合适的问题名称,但我认为下面的示例会很清楚。
以下两者之间的根本区别(内存方面)是什么:
包含以下代码的 DLL:
class ISDLConsole { /* interface */ };
class SDLConsole: public ISDLConsole { /* implementation */ };
__declspec(dllexport) ISDLConsole *Create()
{
return new SDLConsole();
}
与已与此 DLL 动态链接并调用的客户端:
ISDLConsole * pClientSDLConsole = Create();
boost 的客户端,动态链接,并使用它们的容器之一,如下所示:
boost::numeric::ublas::vector<double> v(1000);
现在,如果我没有假设有什么不对的话,在我看来,在这两种情况下,都有一个客户端与 DLL 链接,调用一个方法(在 boost 情况下,它是 vector::vector() c'tor) 分配动态内存。
我假设最好用ISDLConsole * pClientSDLConsole = new SDLConsole();
替换ISDLConsole * pClientSDLConsole = Create();
(如果可能导出class本身)并且只在客户端分配内存,对吧?
所以:
- 1 和 2 之间的根本区别(内存方面)是什么?两种情况在 memory-accorss-dll 方面是否相同?如果是,请说明如何。
- 如果它们不相同,为什么有人会建议跨 DLL 分配新对象而不是按照我上面提到的 'boost' 方式(如果可能)。
- 如果我想编写自己的容器并将其放在一个单独的 DLL 中,它的哪些部分应该是“__declspec(dllexport)ed”?这是否意味着内存将跨 DLL 移动(假设我的容器分配动态内存)?
欢迎就此主题进行任何澄清。
非常感谢。
ISDLConsole 示例的来源是this accepted answer, which BTW contradicts this 接受的答案。
在堆分配方面,我看不出有什么不同。在这两种情况下,您都会在堆上分配一个 class 实例。堆中的实例化对象应该占用相同数量的内存,无论它是在主要可执行文件还是库中实例化。
就代码而言,我希望两种方法之间存在几个字节的差异。背景噪音,我不会担心。
- 代码
pClientSDLConsole = new ISDLConsole();
将无法编译
因为 ISDLConsole 是一个接口(抽象class)。
- 代码
pClientSDLConsole = new SDLConsole();
只有当DLL时才会编译
开发人员在 public header 中声明了 SDLConsole 并将其导出。但
它与隐藏实现的原则相矛盾。
- boost::vector 方法根本不同:所有矢量代码
内联,没有什么可导出的。一些 boost 库不遵循此规则,例如boost::filesystem.
我想不出更合适的问题名称,但我认为下面的示例会很清楚。
以下两者之间的根本区别(内存方面)是什么:
包含以下代码的 DLL:
class ISDLConsole { /* interface */ }; class SDLConsole: public ISDLConsole { /* implementation */ }; __declspec(dllexport) ISDLConsole *Create() { return new SDLConsole(); }
与已与此 DLL 动态链接并调用的客户端:
ISDLConsole * pClientSDLConsole = Create();
boost 的客户端,动态链接,并使用它们的容器之一,如下所示:
boost::numeric::ublas::vector<double> v(1000);
现在,如果我没有假设有什么不对的话,在我看来,在这两种情况下,都有一个客户端与 DLL 链接,调用一个方法(在 boost 情况下,它是 vector::vector() c'tor) 分配动态内存。
我假设最好用ISDLConsole * pClientSDLConsole = new SDLConsole();
替换ISDLConsole * pClientSDLConsole = Create();
(如果可能导出class本身)并且只在客户端分配内存,对吧?
所以:
- 1 和 2 之间的根本区别(内存方面)是什么?两种情况在 memory-accorss-dll 方面是否相同?如果是,请说明如何。
- 如果它们不相同,为什么有人会建议跨 DLL 分配新对象而不是按照我上面提到的 'boost' 方式(如果可能)。
- 如果我想编写自己的容器并将其放在一个单独的 DLL 中,它的哪些部分应该是“__declspec(dllexport)ed”?这是否意味着内存将跨 DLL 移动(假设我的容器分配动态内存)?
欢迎就此主题进行任何澄清。 非常感谢。
ISDLConsole 示例的来源是this accepted answer, which BTW contradicts this 接受的答案。
在堆分配方面,我看不出有什么不同。在这两种情况下,您都会在堆上分配一个 class 实例。堆中的实例化对象应该占用相同数量的内存,无论它是在主要可执行文件还是库中实例化。
就代码而言,我希望两种方法之间存在几个字节的差异。背景噪音,我不会担心。
- 代码
pClientSDLConsole = new ISDLConsole();
将无法编译 因为 ISDLConsole 是一个接口(抽象class)。 - 代码
pClientSDLConsole = new SDLConsole();
只有当DLL时才会编译 开发人员在 public header 中声明了 SDLConsole 并将其导出。但 它与隐藏实现的原则相矛盾。 - boost::vector 方法根本不同:所有矢量代码 内联,没有什么可导出的。一些 boost 库不遵循此规则,例如boost::filesystem.