我最近一直在研究使用C ++创建DLL的过程,偶然发现涉及ABI兼容性的“抽象基类与Pimpl惯用语”的讨论。我是处理DLL的新手,所以如果我弄错了术语/概念,请耐心等待。这是我的故事:
我在CodeProject.com处已读过本文,作者在其中声明使用抽象接口是可行的方法。
总结:您有一个抽象基类class IFoo
,一个工厂方法extern "C" __declspec(dllexport/dllimport) IFoo* createFoo();
和class FooImpl
接口的实际实现IFoo
,该接口实际上是实例化的,由createFoo()
返回。
到目前为止很好。
现在我发现有人认为只有Pimpl-Idiom可以保留ABI兼容性(What's is the point of PImpl pattern while we can use interface for the same purpose in C++?,Pimpl idiom vs Pure virtual class interface ),我有点困惑:
我理解pimpl的方式:您有一个class Bar
持有一个指向class BarImpl
的指针,其中包含所有实现细节。
我的问题:
如果在两种情况下我都仅更改内部工作方式(更改class FooImpl
或class BarImpl
),则两种情况下代码“面向用户”的ABI不会改变还是改变?
另一方面,如果我对class Foo
或class Bar
进行更改,这两种方法都将明显破坏ABI兼容性,对吗?
如果我对使用抽象基类的ABI兼容性的假设是错误的。如果我仅仅对库代码的内部内容进行更改,是否必须在DLL中使用抽象基类的混合来真正保持ABI兼容?
我希望我能清楚地表达出我不清楚的地方;)
编辑:通过“更改内部结构”,我还指的是在实现类FooImpl
和BarImpl
中添加/删除成员/方法。