Dan, Dave, On Tue, Apr 4, 2017 at 11:53 AM, Daniel Mihai <Daniel.Mihai at microsoft.com> wrote: > > On the other hand, my experience with GCC symbol visibility on large C++ > libraries that already used Windows style _declspec(dllexport) based macros > was quite positive, especially since it allowed the compiler to generate > better binaries in some cases than the linker script based approach. > > [DM] As you said, name mangling is still a problem for C++ code ? even if > you use _declspec(dllexport). >
Could you elaborate? I don't recall running into name mangling problems when using __declspec(dllexport) on Windows builds of the C++ libraries I worked on in the past. Are you referring to incompatible mangled names between __declspec(dllexport)-enabled binaries generated by different compilers? > I'm certainly interested in understanding why _declspec(dllexport) doesn't > scale well. Should we take that discussion to a separate thread? > > [DM] Here?s what I have learned while I was trying to fix the old > OC_EXPORT in IoTivity: > > 1. Sometimes we need to import or export a function owned by > someone else ? e.g., export a function implemented in one of the IoTivity > extlibs. Adding OC_EXPORT into extlibs headers can be messier than adding a > *.def file. > That seems like an orthogonal issue. Explicitly exporting a symbol from a library in extlibs that previously wasn't exported implies there is a problem with the way we're using the library in question or with its API. Regardless, that library should define it's own set of EXPORT macros. IoTivity export macros should not be used inside such third party libraries. > 2. This is harder to explain, but let me try. Typical use of > OC_EXPORT is to have: > > a. An Include/ directory, with all exported function declarations > > b. A dll/ directory, with the source code for the exported functions > > c. An app/ directory, with the consumer of exported functions > Right. This is similar to how many software packages intended for use on Linux and other UNIX-like platforms structure their source directories. > d. The dll/ directory uses #define OC_EXPORT __declspec(dllexport) > > e. The app/ directory uses #define OC_EXPORT __declspec(dllimport) > > f. But, it is common in IoTivity to both import some APIs, and > export other APIs, in a single module/LIB. So, such module cannot easily > use either __declspec(dllexport) or __declspec(dllimport) > > g. As a workaround for (f), we could define a whole bunch of macros > OC_EXPORT_1, OC_EXPORT_2, OC_EXPORT_3, OC_EXPORT_4, etc. and carefully > sprinkle some of them before each #include. But this seems bizarre and > unsustainable. > I don't think it's that hard to maintain. Each shared library / DLL would define it's own EXPORT macro in a publicly accessible header. Generation of that header for each library could even be done through a script since it would be boilerplate for each library, and need only be done *once* per library. Use of an incorrect EXPORT macro in the shared library implementation should be detectable at link-time. Otherwise there is nothing that library importer needs to do at compile-time. This is basically the approach described in the example in GCC symbol visibility wiki. It's also the approach used in C++ projects I've worked on with over 40 shared libraries, where many of those libraries used exported symbols from the other shared libraries in the same project. -Ossama -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.iotivity.org/pipermail/iotivity-dev/attachments/20170404/3f2c6fc3/attachment.html>
