Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Only in the sense that C++ itself "uses the C ABI"

Not at all. Qt literally uses the C ABI as a protocol for plugins. I have no doubt they chose it because it's the only inferface simple and stable enough for the task. It is relatively simple and stable precisely because there are zero C++ features involved. I thought that alone was damning enough so I didn't elaborate further.

What you said is absolutely true: the objects returned by those C functions are accessed by the real C++ ABI with vtables and everything. That's a massive problem and they shouldn't have been designed this way. Look at the mess this causes:

https://forum.qt.io/topic/119767/qt-plugin-fixing-c-abi-prob...

> I know that C++ don't have Aplication Binary Interface - ABI compatibility between compilers (example: MSVC, MingW, Clang and ICC).

> Besides that, the C++ ABI compatibility can be broken even using the same compiler with different version (example: MSVC 2003 and MSVC 2019).

> Example: If the main C++ application was compiled using MSVC 2003, all plugin developers MUST HAVE and MUST USE the exactly same compiler to build your projects, in this case MSVC 2003. Which is not good.

> Looking in the internet I found a way to fix that: Creating a C Wrapper of my C++ Interface Abstract Class.

The solution is, of course, to get rid of all this C++ business and restrict yourself to the C ABI. This is apparently the fate of every ABI that isn't C. When even that is annoying enough to deal with, nobody is ever going to want to deal with anything more complex.



I don't understand this point. You say "Qt uses the C ABI for plugins", then immediately claim that "because they use the real C++ ABI with vtables and everything" it is a "massive problem" that shouldn't have been designed this way.

First, Qt is using the C++ ABI, even for dynamically loaded plugins. This much should be obvious: it is calling C++ methods through a C++ abstract base class, passing C++ objects as arguments, on which C++ methods are going to be invoked. How is this not the C++ ABI?

The one thing that may be confusing is that one uses C APIs (dl, etc.) for discovery, but this is because C++ _is_ using the C ABI. C++ symbols are in the platform executable format's symbol table, after all. How is one going to export and GetProcAddress a plugin object factory method in C++?

Second, it is not really a "massive problem": it simply works, and it is used by Qt itself for critical functionality such as the image format loaders (which I think people would rather notice if they were not working).

The usual MSVC++ stuff you mention applies for _all_ Windows based development (even C! you are not supposed to mix MSVCRT versions in Windows!), and specifically applies for _linking to Qt itself_. Why would it now become an issue for plugins, which obviously must all link to a compatible version of Qt? Ensuring one uses the same version of the MSVC compiler is not so different as ensuring the use of the same version of MSVC that was used to build Qt, or even to use the same version of Qt for the base and gui libraries...

There is really not that many more issues with the C++ ABI than with the C ABI; they are more visible because people tend to use & expose more of the C++ ABI. E.g. it is rather unlikely to pass FILE objects to libraries, while it is rather common to pass std::string objects. If you send to a module with a different ABI, you are going to crash (if you are lucky enough).


> How is one going to export and GetProcAddress a plugin object factory method in C++?

How, indeed. That's exactly my point. How could anyone possibly do that? You'd need to implement a C++ compiler frontend in your GetProcAddress and dlsym functions just to resolve C++ symbols. This is why they had to use the C ABI for what you call "discovery". The fact is even getting a simple pointer to a C++ object would be pretty much impossible without a C ABI in there.

To say nothing of actually calling the functions returned with C++ calling conventions. The only reason this QtPlugin business even works is you're also writing C++ code and can therefore use C++ calling conventions. Even that is a dance because those conventions are different for every compiler and even individual versions of the same compiler.

> Ensuring one uses the same version of the MSVC compiler is not so different as ensuring the use of the same version of MSVC that was used to build Qt, or even to use the same version of Qt for the base and gui libraries...

So your solution is to just make sure everyone is using the same compiler? Yeah, easier said than done. Even in the free software ecosystem which hates binary interfaces and has the capacity to rebuild the world if necessary, breaking ABIs cause chaos and pain for everyone.


> How, indeed. That's exactly my point. How could anyone possibly do that? You'd need to implement a C++ compiler frontend in your GetProcAddress and dlsym functions just to resolve C++ symbols

I still don't follow. C++ symbols are C symbols. Can you put an example of how you can get more C++ than Qt is? If you mean mangling, I don't think you need an entire C++ compiler for it. But even standard C++ contains some escape hatches to avoid mangling (one of them being 'extern "C"').

> The only reason this QtPlugin business even works is you're also writing C++ code and can therefore use C++ calling conventions.

I don't disagree with that. My point was that dynamically loadable plugins in C++ -- with "vtables and all" -- not only work, but are in fact frequently used.

> Even that is a dance because those conventions are different for every compiler and even individual versions of the same compiler.

> So your solution is to just make sure everyone is using the same compiler?

This is an entirely different problem that affects _all_ languages. On Windows, as I mentioned, there are even multiple C ABIs (incl multiple calling conventions) and standard libraries and everything you can think of. This is done intentionally, so that they can more easily preserve binary compatibility with older versions. Other platforms have made different compatibility decisions.

I think people significantly exaggerate how much "pain" the situation causes (and this comes from someone who has distributed commercial multi-platform C++ software for 20+ years). In any case this is a common problem, dynamic plugins or not, C++ or C. And definitely, this is not something so annoying I would trade dynamic linking for. But that's off topic.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: