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.
Related
In relation to this topic: What is the copy-and-swap idiom?
It states that one class should at most handle one resource. What is meant by resource?
EDIT: For example I have a class that handles the information for each monitor, and contains an array of the desktop pixels. Would the array and only the array be considered a resource? Would the array of monitors that hold the monitor information and array of the desktop pixels another resource, that would require another class? It is in another class, but is that what is meant?
I have searched here and Google but only find more information relating to the rule of three or resource files (*.rc and MSDN). Nothing that relates to a definition.
That question is referring to concepts in C++ in general. In this case, it is also using the general concept of a "resource": an object, usually external, provided by an outside source, that a block of code uses. It's the same as a "resource" in real life.
In the case of copy-and-swap, it is referring to what your C++ class represents. The idea is simple: each instance of your C++ class will provide access to a given resource. For instance, let's take a file on disk. The resource is the file; the operating system provides access to that file. Your C++ class would wrap around the operating system's API calls to read and write to that file.
The question that you linked is asking about how to mix these classes with C++'s initialization rules. How you follow these rules is going to be shaped by what accesses the outside source lets you use and what you personally need to do.
Of course, your program can also have its own resources. For example, a global array that maps one type of enumeration to another type of enumeration could be a resource in your program. So the answer to your question of "what should be a resource in my program" is "it really depends on how you wrote your program".
Windows programs also have their own "resources", such as bitmaps, icons, dialog box control layouts, menu layouts, localized strings, and other stuff. To allow these things to be embedded in the output binary, Windows provides its own system, and also calls all these "resources". A .rc file is merely how you would list all of these Windows resources; you build that into your Windows program.
GLib (which GTK+ is built on top of), Qt, and the various Apple APIs have their own analogous systems, each of which also have "resource" in their names.
(You can write C++ classes that provide access to all these specific resources too; in this case, the resource is the resource.)
But it is very important when reading not to confuse he general term ("resource") for the specific technology (Windows resources) and vice versa, especially for such an abstract concept as a resource. Keep that in mind as you continue your programming journey.
Resources, are things like: raw pointers that need to be deleted (that's why we have smart pointers like std::unique_ptr, std::shared_ptr), files that need to be properly closed (that's why we have std::fstream), std::thread (to manage the raw handles that you would have to otherwise manage yourself in different operating systems). std::reference_wrapper manages references... and so on. As you may have noticed all of them manage a single resource, not more.
The idea is that you don't want a single unique_ptr to manage 2 pointers for you. You would create two unique_ptr classes for each raw pointer.
For your specific question which you have edited, generally what you wanna do is:
create a class MonitorsManager that manages all the monitors (that's his task)
create a class MonitorInfo (that manages a single monitor information and the pixels
You will notice things get easier if you have a good design, because in the future you will want to be able to easily edit and update those classes, and if you mix everything, it's gonna be really hard, trust me.
Also, your MonitorInfo class should not have any dependency on MonitorsManager because if people has to include the class "MonitorsManager" in their project in order to use your "MonitorInfo" class, then you have failed. Not everyone has multiple monitors, some may have a single one.
About the last year I did Java(Android)-programming, and did C# the Year before that. About a month now I'm learning C++, and since I got over friends, inheritance and stuff, I got a few questions, since I haven't been working with it up until now:
Is there a way for a class to define friends later on, because they need to exchange information or something. e.g. is there a way to define a 'random' friend later on? what do you need for that? The function's name or the address of the class?
Or is there generally a way to change the code from the program itself, so that it won't be necessary to recompile? e.g. creating new functions, classes or so?
I'd be very happy about any answer about that.
What you want to do is not possible with C++. If you need that sort of dynamically changing the program, you are better advised using a more dynamic higher-level language like Lisp.
friends can only be added to a class by modifying its source code. This is a feature, not a bug.
There are two ways to extend functionality like that.
Use dynamically loaded modules with the extended functionality. These modules supply a specific interface, and can be compiled separately from the main program.
Add support for scripting - allow users to add write scripts, and run them from inside your program.
The first solution is easier, depending on how much control you want to give those scripts.
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++...
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".