2

A first in my professional life, I must deliver a DLL to a customer that contains our base, generic software and an interface that makes it work the way the customer wants it + allows the customer to feed in inputs and read outputs.

Now my big problem here is, I may not show anything to my customer that he doesn't absolutely needs to know, because of intellectual property. This includes data types, which therefore I cannot even show him the signature of any of our internal methods. I have created data types and structures which mimic our own internal ones but which for example voluntarily omit unnecessary atrributes/elements or give them different names to hide hints to our private internal logic. And then the methods that get data map our own data structures and type into those. You get the picture.

Also, this time from a pure software architecture point of view, I do not want him to access certain members, attributes, variables ... because I do not need him to know that they exist or do not want him to modify them when he pleases and how he pleases. Yet they are solely related to that interface, and are not at all part of our internal software.

What I have right now is a class which serves as an interface, which he can instantiate. It basically provides get methods for output, methods to feed input and launch update calculations, and getters and setters for other parameters and values (like software versions or current state). Actual data variables for those parameters and other variables are hidden in my CPP file which gets compiled into the DLL, so they are not even declared as attributes of the class that we use as interface in the H file that I give to him, not even as private, and he doesn't know about them - he only has the getters and setters.

What design pattern should I be using here ? Could I actually put my variables in the H file that I share with my customer, as attributes of the class, as private ? But then, would he be able to change them from private to public, and by writting new methods for the class, accessing them and modifying them freely without the compiler complaining ? Could I otherwise contribute to my class and extend it in my CPP file or some other H file that he would not have access to ?

So many questions, as it is all new for me. But you get the general picture : I want to share the strict necessary, the utmost minimal information with my customer in this H file so he can make my DLL work and get his data outputs. And no more.

Thanks in advance, Charles

Charles
  • 696
  • 6
  • 22

2 Answers2

4

First, you should consider building a DLL with a pure C interface, as having a C++ interface with STL classes at DLL boundaries is highly constraining (e.g. your client has to use the same Visual C++ compiler version and dynamically-link to the same CRT flavor you used to build the DLL).

At this point, you are free to develop a thin layer that will shield/hide your C++ implementation (compiled in the DLL and as such delivered as binary) to the customer.

You may also provide a simple public header file that could wrap the C interface layer exposed by the DLL in an nice C++ object-oriented way (kind of like ATL and WTL do for Win32 pure-C API functions).

Mr.C64
  • 37,988
  • 11
  • 76
  • 141
  • In fact we already did that, as we indeed faced issues due to varying name-mangling patterns accross different compilers. This was fixed no later than yesterday, as I know compile under Visual Studio Express 2015 like my customer. We haven't tried reverting to the C++ interface yet. And if I indeed limit myself to a C interface, and put all my objects as static variables in my source file, then we're okay. But now that we think we can use C++, the question arises again. – Charles Oct 06 '16 at 10:45
  • @Charles: It's not only about name mangling differences, but also about more profound issues, e.g. different _implementations_ of STL data structures between different versions of Visual Studio. You don't need static variables. You can just wrap C++ class method in C functions (e.g. `MyClass` ctor becomes `MyClass_Create()`, `MyClass::DoX()` becomes `MyClass_DoX()`, etc.), and pass the `this` pointer as an opaque pointer. – Mr.C64 Oct 06 '16 at 10:49
  • Ok so you're clearly telling me to just resort to a list of C methods which in the background to some C++ stuff. So basically what we have right now, which is very similar to what you described. – Charles Oct 06 '16 at 10:56
  • Yes, that's the safest more robust way to build a DLL. You can then provide to your customers an header file that wraps those C-interface exported functions back in a nice OO C++ way. An alternative would be building a DLL that exports COM objects/interfaces, but it's probably too much work and unnecessary in your case. – Mr.C64 Oct 06 '16 at 11:00
  • But how can I perform any C++ in this H file if I am going to compile with it and then share it with another person who may have a different compiler ? An example of wrapping is, putting all my C headers into a namespace. But then ... they get name-mangled again ! – Charles Oct 06 '16 at 11:04
  • This .h file would just be a _tiny_ object-oriented wrapper on the C API functions exported by your DLL. This file would contain just short inline methods wrapping your C-interface DLL functions in C++ classes. Think of e.g. the `CWindow` class implemented in ATL headers that wraps Win32 `HWND`-related functions (like e.g. the Win32 C-interface function `SetWindowText(HWND, const TCHAR*)` becomes `CWindow::SetWindowText(const TCHAR*)`. – Mr.C64 Oct 06 '16 at 11:25
  • Do you have any links to those examples ? – Charles Oct 06 '16 at 11:51
  • @Charles: You can just browse the ATL/WTL headers :) But what matters is the concept. Moreover, I heard of [this CppCon 2014 presentation on the _"hourglass model"_](https://www.youtube.com/watch?v=PVYdHDm0q6Y) that could come in handy for you; but I haven't watched it. – Mr.C64 Oct 06 '16 at 11:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/125129/discussion-between-mr-c64-and-charles). – Mr.C64 Oct 06 '16 at 17:13
2

What design pattern should I be using here ?

Please refer to pimpl idiom for more details.

Could I actually put my variables in the H file that I share with my customer, as attributes of the class, as private ? But then, would he be able to change them from private to public, and by writting new methods for the class, accessing them and modifying them freely without the compiler complaining ?

Yes, he would. With pimpl it is still possible, but much more hard and requires reverse engineering.

Graham
  • 6,577
  • 17
  • 55
  • 76
Alexey Guseynov
  • 4,743
  • 1
  • 15
  • 28
  • This doesn't address the DLL question at all. – Moo-Juice Oct 06 '16 at 09:36
  • Read it. So this basically relies on the forward declaration of the body of the implementation, including variables that I would like to hide, and whose declaration is 1. postponed to a later stage in the compilation process without this raising an error quite yet and 2. located in another file that is not shared with the customer. If my customer then only has an H file without the declaration of the body of the implementation and my DLL with the declaration (and definition) of it inside, is he going to be able to compile ? – Charles Oct 06 '16 at 09:38
  • @Moo-Juice That's what I fear. Again, and unless someone has a better suggestion, my customer will only have a DLL and an H file declaring the exported stuff that he needs. – Charles Oct 06 '16 at 09:38
  • 1
    @Moo-Juice, Charles asks how to hide all possible implementation details from his public headers. This is what pimpl is exactly designed for. Customer will be able to compile code without knowing definition of implementation class. – Alexey Guseynov Oct 06 '16 at 09:40
  • @AlexeyGuseynov, I believe Charles' question is more about the creation and compilation of said DLL with *exported* functions and appropriate header files with the necessary pre-processor directives (compiler dependent) – Moo-Juice Oct 06 '16 at 09:45
  • @Moo-Juice Correct. I compile the DLL, and deliver it as binary. Any and all things that pertain to our internal software which I wrap must be hidden, and ond exported functions which go grab data and do stuff must be as minimalistic as possible. Also yes, we have the compiler issue, but it is fixed now, as we both compile under Visual Studio Express 2015. – Charles Oct 06 '16 at 10:42
  • 1
    @Moo-Juice, there is not much special in creation and compilation of the DLL. You use pimpl to hide implementation details for all classes that you export. You separate headers to public and internal as it is done usually (public go to include folder, private headers are near their .cpp files). Of course you mark public classes with dllexport, but this does not seems to be a problem for Charles. Then you compile it and distribute dll, lib and public headers. No magic except pimpl. – Alexey Guseynov Oct 06 '16 at 10:54