As the title suggests, is it correct or valid to import/export static data from within a C++ class?
I found out my problem - the author of the class I was looking at was trying to export writable static data which isn't supported on this platform.
Many thanks for the responses however.
An exported C++ class means that the DLL clients have to use the same compiler as the DLL because of name mangling and other issues. This is actually a pretty big problem, I once had to write C wrappers to a bunch of C++ classes because the client programs had switched to MSVC9, while the DLL itself was using MSVC71. [There were some other complications with switching the DLL to MSVC90]. Since then I've been quite skeptical about this business of exporting classes, and prefer to write a C wrapper for everything.
Now, if you're willing to pay the price of exporting classes, I'd say that exporting static data doesn't make the problem any worse. Arguably, among the kinds of things you could export, it is safest to export static constants. Even so, I'd rather not do it, because like Timo says, you're now locked into this implementation.
One of the frameworks that I worked on required its clients to provide a set of error code constants. Over time, we found that using a simple bunch of constants was too brittle, and we switched to an OO design. We had a default implementation that would return the common error codes, but each of the error codes was accessed using a virtual function which could be overridden by individual clients - and they used it from some advanced device specific error handling. This solution proved far more scalable than the one based on exporting constants.
I'd suggest that you think long and hard about how you expect the component to evolve before you exporting static variables.
Is it correct inasmuch as it'll work and do what you expect it to? Assuming that you are talking about using _declspec(dllexport/dllimport) on a class or class member, yes, you can do that and it should give you the expected result - the static data would be accessible outside your dll and other C++ code could access it provided that that C++ access specification (public/protected/private) wouldn't block outside access in the first place.
Is it a good idea? Personally I don't think so as you would be exposing class internals not only within your library but to the outside world, which means that it will be pretty much impossible to change what is an implementation detail at the end of the day. Ask yourself if you are 100% certain if the interface of this class and large parts of its implementation will never, ever change...
dllexport (or import) on a class's (non-static) data member does nothing. Exported "things" are either functions or global data (though this is a questionable design choice). dllexport on a class is just a shortcut for saying "export all of these functions".
Related
Watched 2 CppCon Gabriel Dos Reis' talks about modules TS.
And as I remember he didn't want to export any private members/functions, so other modules won't be able to use them at all.
I understand his position, but won't it conflict with future C++ reflection? For instance when C++ has a reflection that can enumerate all class functions, shouldn't it be able to enumerate private functions too?
I know, accessing private functions is bad, but in rare extreme cases it is necessary (how const_cast is sometimes necessary, despite the fact that a developer who writes it should feel terrible)
Edit:
And there is at least one exception for "not exposing privates" - if classes use "non virtual interface" pattern
Modules do not (as presently defined) change how C++ works at a fundamental level. It changes a few things with what names are accessible and from where they are accessible. But it doesn't change how the language works with those names.
So if static reflection comes along and permits you to talk about private members of a class, then you can talk about private members of a class. Whether that class definition came to you through a #include directive or a module inclusion is irrelevant.
To allow what Gabriel Dos Reis wants would require an explicit exception to the reflection rules to be made. And that is unlikely to happen.
And it's not really that important either. While being able to remove from module files private members (and any non-exported types they work with) would make module files quite a bit smaller, I don't think this extra module file size will be that big of a deal. The main thing it would allow you to do is to make certain changes to module source code that wouldn't require recompiling modules that include your module. But a well-modularized codebase ought to have relatively quick compilation anyway. So while it would be nice, it's hardly essential.
I'm new to using DLL's in C++ and I am wondering how to sucessfully load and use classes contained in a DLL without getting a "corrupted stack", a "null pointer" or any application crash ^^. This is a bit confusing to me for now.
Even if it might be safer I don't want to use interface class because it seems too complicated to use. I know that I should have the same include in both DLL and application to prevent crashes. That means that my include file should mention members name.
Here is the problem :
I want to distribute my software (DLL + include file) and I don't want
my customers to see the architecture of my project. But the only class
I want to export from my DLL has as member, objects from other
classes. So my class is dependent of other classes and so on in
cascade.
Is it possible to provide only one include file of one class with just useful methods without having risks of crashes ? If no, what solutions might fit my needs ?
Thanks
FIrst of all, if you use the same include in DLL and in the application using it, if both were compiled with the same compiler and compatible settings, and both use the same runtime library (DLL one, not statically linked), you should have none of the problem you fear.
If you want to hide details of your DLL and provide an alterered, simplified header to the DLL users, you work on your own risk. For example, if there are data members missing (even private ones) of if there are virtual functions missing (even private ones), then it might probably crash, or worse, corrupt something without being noticed. So I'd strongly advise you not to consider this approach unless you're very very experienced with the assembler generated by your compiler.
If you want to hide implementation details of your class, the best approach would probably to design your library around the PIMPL idiom.
DirectX 9 / C++
Do you declare d3ddevice global to your entire app/game or do you pass into classes that require the d3ddevice?
What is the usual way?
I understand it (and this may be wrong) that if you declare it globally, all classes and functions will be burdened by header memory that declares that global variable within the class after compiling?
I can be more specific about my question my application but, I'm just looking for the typical way.
I know how to start the d3ddevice etc, it's just a question about what is best?
I would recommend you wrap everything within a class and never put anything in global because global variables can be accessed from anywhere and that can make it very hard to keep track of the variable and who is and isn't using it.
Little bit late to the party here, but I also just recently stumbled into this same design question. It's a little surprising to me that there isn't more talk about it on the internet. I even tried perusing random github libraries to see if I could glean how others did it. Didn't find much. I also have an example of when you can't declare the d3d device as a global/static object. For my game/engine, I have a dll which serves as my engine framework. This dll is consumed by both an editor, and a game client (what people will use to play my game). This allows both things (and other applications in the future if desired) to access all of the world objects, math code, collections, etc.
With that system, I can't think of a way to make the Device object static, and still use it in both the editor and the client. If this were just a game client, or just an editor, then sure, it would be possible. Instead, I've pretty much decided to bite the bullet and pass Device to whatever needs it. One example, is a class that generates vertices at runtime. I need a pointer to Device for rebuilding the class.
I really just wanted to post this here, because I've been thinking about it for most of the day, and it really seems like this is the best way to handle it. Yeah, it sucks to have to pass the Device to nearly everything. But there's not really anything you can do about it.
I'm pretty sure this problem isn't new, and pretty sure it's hard to solve. Hopefully I'm wrong about the latter.
I'm trying to use the Loki::Singleton from Modern C++ Design in a program of mine.
However, I can't seem to get it to work across DLLs. I think I know why this is happening: the templated code gets instantiated in every source module, so instead of there being one global variable, each module has its own.
Obviously, this makes the Singleton very much non-single.
Is there any way to get around this behavior?
I see in the Loki source directory that they have a specific SingletonDLL directory under test, looks like they use an exported, explicitly instantiated template (which would work). Hopefully that contains the code you want.
Note this is not going to address the question. An explicitly instantiated and exported singleton should do the trick...
-Rick
Check out #pragma data_seg here basically, you need to declare an instance of the singleton in a shared section of your code. By default statics are scoped to the dll.
It may get tricky with templates, but this is the path to success here that doesn't involve passing / copying static data around.
You are probably correct that each DLL has its own instance of the singleton. I'm not that familiar with the Loki implementation and the source code isn't a lot of fun to figure out.
Possible solutions are:
Not using singletons. This is actually my usual preference because you can avoid whole classes of issues by changing your design to not need them. For a long rant on why Singletons may be harmful see this Yegge post. I'm not THAT vehemently against them but 95% of the time Singletons cause many more problems than they solve (if they actually solve any)
Copying static members across DLL boundaries. I've also done this as a hack, where the DLL gets a pointer from an application or another DLL, and resets its own copy of the static class member to the pointer passed from outside. It's evil, it's dirty, you can't clean up after it, but it does work.
Is it possible to implement monkey patching in C++?
Or any other similar approach to that?
Thanks.
Not portably so, and due to the dangers for larger projects you better have good reason.
The Preprocessor is probably the best candidate, due to it's ignorance of the language itself. It can be used to rename attributes, methods and other symbol names - but the replacement is global at least for a single #include or sequence of code.
I've used that before to beat "library diamonds" into submission - Library A and B both importing an OS library S, but in different ways so that some symbols of S would be identically named but different. (namespaces were out of the question, for they'd have much more far-reaching consequences).
Similary, you can replace symbol names with compatible-but-superior classes.
e.g. in VC, #import generates an import library that uses _bstr_t as type adapter. In one project I've successfully replaced these _bstr_t uses with a compatible-enough class that interoperated better with other code, just be #define'ing _bstr_t as my replacement class for the #import.
Patching the Virtual Method Table - either replacing the entire VMT or individual methods - is somethign else I've come across. It requires good understanding of how your compiler implements VMTs. I wouldn't do that in a real life project, because it depends on compiler internals, and you don't get any warning when thigns have changed. It's a fun exercise to learn about the implementation details of C++, though. One application would be switching at runtime from an initializer/loader stub to a full - or even data-dependent - implementation.
Generating code on the fly is common in certain scenarios, such as forwarding/filtering COM Interface calls or mapping OS Window Handles to library objects. I'm not sure if this is still "monkey-patching", as it isn't really toying with the language itself.
To add to other answers, consider that any function exposed through a shared object or DLL (depending on platform) can be overridden at run-time. Linux provides the LD_PRELOAD environment variable, which can specify a shared object to load after all others, which can be used to override arbitrary function definitions. It's actually about the best way to provide a "mock object" for unit-testing purposes, since it is not really invasive. However, unlike other forms of monkey-patching, be aware that a change like this is global. You can't specify one particular call to be different, without impacting other calls.
Considering the "guerilla third-party library use" aspect of monkey-patching, C++ offers a number of facilities:
const_cast lets you work around zealous const declarations.
#define private public prior to header inclusion lets you access private members.
subclassing and use Parent::protected_field lets you access protected members.
you can redefine a number of things at link time.
If the third party content you're working around is provided already compiled, though, most of the things feasible in dynamic languages isn't as easy, and often isn't possible at all.
I suppose it depends what you want to do. If you've already linked your program, you're gonna have a hard time replacing anything (short of actually changing the instructions in memory, which might be a stretch as well). However, before this happens, there are options. If you have a dynamically linked program, you can alter the way the linker operates (e.g. LD_LIBRARY_PATH environment variable) and have it link something else than the intended library.
Have a look at valgrind for example, which replaces (among alot of other magic stuff it's dealing with) the standard memory allocation mechanisms.
As monkey patching refers to dynamically changing code, I can't imagine how this could be implemented in C++...