I see that DirectX 9 has multiple DLL versions, like
d3d9.dll
d3d9_25.dll
d3d9_42.dll
d3d9_43.dll
I'm wondering what the differences are, and how I can detect it? I have always been using GetModuleHandle("d3d9.dll");, but if an application has d3d9_43.dll, then my code will not detect that the application is using DirectX, will I? How would I go about detecting it without hardcoding all the DLL versions?
If code uses D3D9, it will always use d3d9.dll at some point. Typically this is in the import table, but it can be dynamically linked (LoadLibrary). d3d9.dll provides the init code for D3D (and COM, when needed), and exports Direct3DCreate9 to create a new IDirect3D9Object.
d3d9.dll is used regardless of version, the version is specified by passing D3D_SDK_VERSION to Direct3DCreate9 as the only parameter. This indicates what version should be used, not any DLL names.
The numbered files most often seen are D3D X files. These are versioned, with _43 referring to the June 2010 SDK (each SDK release has one, I believe). If a program needs the helper functions provided in D3DX, the latest version from the SDK is typically linked against, with the numbers keeping them separate.
The D3D9_[number] files which are not part of D3DX follow the same system (and likely have the same SDK version to number relation) and similarly provide version-specific features.
This is not say d3d9.dll is not used; a vast supermajority of software uses that file (in fact, I've not personally seen a D3D9 app which didn't). Linking against D3D9.dll and passing the SDK version is the proper and recommended method for using D3D9. Testing for it is safe and reliable, and the simplest way to check the version is to intercept the call to Direct3DCreate9.
Related
This question already has answers here:
When do I need to use an OpenGL function loader?
(3 answers)
Closed 3 years ago.
I am learning now OpenGL and writing some geometrical abstractions over it for personal usage. I want my code to be maximally portable and I want to have GL context initialized in caller code (by means of FLTK, wxWidgets, WinAPI or any else supported platform).
I am reading now this popular article: https://learnopengl.com/Getting-started/Creating-a-window
Authors suggest there to use GLAD library, because this library provides creation of GL context (which does not fit me) and also it is used for 'retrieving addresses of functions' (quote: "Since there are many different versions of OpenGL drivers, the location of most of its functions is not known at compile-time and needs to be queried at run-time.").
My question is the following:
Does compiler really cannot get addresses of Opengl functions from GL-related .obj files which I specify in Linker Settings of Visual Studio? Do I really need to use wglGetProcAddress routine to refer to OpenGL functions? Is it possible to use OpenGL functions like any other functions from linked headers and .obj files?
Authors suggest there to use GLAD library, because this library provides creation of GL context (which does not fit me)
No, GLAD does not create or manage GL contexts in any way, and the website https://learnopengl.com/Getting-started/Creating-a-window never claims otherwise. They use GLFW for context and window management.
Does compiler really cannot get addresses of Opengl functions from GL-related .obj files which I specify in Linker Settings of Visual Studio?
No.
First of all, you do not specify OpenGL-related .obj files for the linker, but on Windows, you might use opengl32.lib, which is the import library file for opengl32.dll which comes with every windows version since Windows 95.
However, this DLL does not contain the OpenGL implementation you are typically using, but it contains Microsoft's OpenGL 1.1 GDI software rasterizer. The actual OpenGL implementation on windows is provided by an Installable Client Driver (ICD) which comes with your graphics driver. For OpenGL 1.0 and 1.1 functions, opengl32.dll will act as a trampoline and will forward the calls to the actual ICD DLL.
If you want to call any OpenGL function beyond OpenGL 1.1 (and that one is from 1997), you have to use the OpenGL extension mechanism in every case, as opengl32.dll does not provide these entry points at all, and the compiler/linker will of course not find them.
I am currently facing a task where I have to integrate an IMU, whose API has been developed using Visual Studios 2015 with an integration software whose API is only compatible with Visual Studios 2010.
I already tried adapting the IMU API to VS2010 but that got too complicated and tedious. It is not doable in a reasonable amount of time.
A solution which I thought of, was to implement a class in VS2015 (let's call it BridgeClass) which would read the desired data from the IMU using a simple struct. This would be implemented as a dll and I could link it to the integration software in VS2010.
However, the part which is unclear is, how could I keep the two libraries separated from each other, so that VS2010 never 'sees' anything of VS2015 that upsets it. Is this possible using a dll? I will have to link the IMU library to the BridgeClass (for example to open the port to and read data from the IMU), will this, in turn, be linked to the integration software and end up being the same as directly integrating the IMU?
I would be very helpful if someone could give me some information regarding this or point me to some helpful links. Thank you!
As long as your DLL's API doesn't use any of the standard library and no exceptions are thrown across the DLL boundary it should work in mixed visual studio versions.
You need to use char* instead of std::string. No std::vector, std::shared_ptr, std::unique_ptr etc.
One other thing which you need to be careful of is that anything allocated in the DLL must be deallocated inside the DLL, this is usually done with a c factory function and a c destructor function that your application can call to create and destroy objects.
Users of OpenGL APIs typically use a library such as GLEW or glad to load OpenGL functions at runtime. Why is dynamic loading the preferred linking method?
Static linking is clearly not an option since programs using OpenGL are typically compiled by the author and distributed to users who have different OpenGL libraries for their particular graphics cards.
That leaves dynamic linking and dynamic loading. It seems like dynamic linking could work since we know the names of all the functions we'll want to access.
Is dynamic linking a viable option? If not, why? If so, why is dynamic loading preferred?
What you want is possible. You can make a loader that is a DLL/SO with a static interface, which will load function pointers from the implementation behind the scenes. It will pipe function calls to the implementation, based on which context is current. Indeed, this is essentially how modern Linux distros work.
This is also how WGL works on Windows... up though OpenGL version 1.1, at any rate.
The reason it is not "preferred" is because it requires effort. Someone has to create and maintain this intermediary library that sits between the application and the driver. Whenever a new extension comes out, the library has to be updated. Whenever a new version comes out, the library has to be updated. And then you have to make sure to link with the right version of this library.
That additional dependency worked out OK on Linux, because it was kept up to date. OpenGL32.dll on Windows however was not. WinNT adopted OpenGL for a while, but Microsoft had also gone off and createdpurchased their own graphics API for Win9x. So they never updated OpenGL32.dll for later OpenGL versions or new extensions. And if they were willing to be non-backwards compatible, I imagine they'd have ditched OpenGL32.dll entirely from their OS.
Since you need a runtime loader to work in Windows, it's easier to just make all platforms work using the same runtime loader (though obviously with a different function fetching the function pointers). And while you could create the kind of DLL you're talking about, it would just be one more OpenGL loading library, one more dependency you have to maintain. Without the centralization that Linux/MESA brings to the table, there's just no point in bothering.
I was thinking that an application could be dynamically linked directly to the driver itself without an intermediate library
You can do that. However, you would be linking to that particular driver's library with a static import library. This means that if you link against NVIDIA's implementation, your application will fail to run on AMD's implementation.
And you can't statically link to import libraries for both DLLs. The reason being that if one static import library cannot be loaded, your application terminates. So unless you have both AMD and NVIDIA's implementations on your machine, you would not be able to run on either one.
Also:
since even though the driver library can't be available at compile time, we still know the OpenGL function names
That assumes that their drivers directly export those names. That is hardly guaranteed.
After all, the WGL/GLX interface is to use wgl/glXGetProcAddress to get function pointers. If the interface between WGL/GLX and the driver is simply to pass the string to the driver's function, then the driver doesn't need to export any functions directly. It exposes its API through a single entrypoint, forcing runtime function pointer loading rather than allowing static linking.
My understanding is that OpenGL loading libraries LoadLibrary/dlopen from dll/dylib/so library files which are themselves graphics card drivers and those driver libraries have symbol tables with OpenGL functions. Which parts of that are wrong?
All parts of that are wrong. You link against the basic interface API (like WGL or GLX). The loading library uses that interface to load function pointers. How the interface API translates loading a function pointer into the driver DLL is a platform-specific issue. On Windows, wglGetProcAddress calls a function in the driver, passing the string name of the function and getting back the function pointer.
On Linux, GLX tends to manufacture functions internally, using late-binding techniques to load the actual driver function later. That is, you can call glXGetProcAddress with some bogus name, and it will return a function pointer shim that, when called, will load the function for the current context from the driver.
The OpenGL wiki gives some insight into the OpenGL function loading process. Not that using the GetProcAddress functions amounts to a form of dynamic linking done outside of the operating system itself. From Wikipedia:
In computing, a dynamic linker is the part of an operating system that loads and links the shared libraries needed by an executable when it is executed (at "run time"), by copying the content of libraries from persistent storage to RAM, and filling jump tables and relocating pointers.
Extensions for OpenGL come out all the time and can be either available or not depending on vendors and driver platforms. The OpenGL wiki states that on MacOSX:
GL functions on OSX have been weak linked since OSX 10.2; this means that you can call them directly and unimplemented extensions will resolve to NULL. Note that this means that you must parse the extension string to determine if a function is valid or not, or your program will crash.
So even if Apple maintains a library to dynamically link with, you still need to add a layer to check whether a given function is available or not depending on the supported OpenGL version and extensions.
I'm maintaining an old project, and now it has to work with another project build with a newer version of visual studio and a newer version of boost. To communicate with other processes, the first project uses a shared memory segment, so now the second project has to read this segment (and write to it) but not create it.
Is this possible? are there any restrictions? I don't seem to find any documentation about it.
Boost versions involved: 1.35 and 1.55 (it might be updated to 1.56)
Visual Studio versions: 8.0 and 2013.
This is an interesting question.
On the library level, I'd assume that no breaking changes exist unless they were document.
However, there are many more things to take into account.
You Are Sharing Memory
This implies you're directly sharing memory representations of your classes.
This implies:
Implies:
You Are Sharing ABI
This already rules out compatibility even if you happen to use slightly different compiler flags, with the same compiler/library versions.
In other words, don't share memory unless you control both ends and can make sure they are binary compatible.
SUMMARY
Boost's shared memory offerings say nothing about data representation (beyond "if you can link it into the same binary, it's good enough for IPC access"). So, if you need this level of isolation, look at
Boost Serialization
combine with EOS Portable Archives for bigger portability
the guy that asks weird things, here, again
I see that they use different executables, for a game that was created for both directx 9 and 10. It is possible to include "d3d9.h" and "d3d10.h" in a code file, then select direct3d 9 functions or direct3d 10 functions, depending on, for example, an argument that acts like a flag? I am not talking about drawing something using a direct3d 10 function using a direct3d 9 context and object.
What I want to do is create a function called init3D(UINT version); Depending on version, it will create a directx 9 or directx 10 object and device. I don't know if that is possible or I must create two different executables (or 3 if I decide to use d3d8, too)
Thanks for your help and forgive my lack of understanding with some of the C++ techniques.
Yes it's entirely possible.
The only issue is that the libraries for both must exist on the target machine. Because you've linked with d3d10 it must be installed on the machine for your .exe to even load even if you want to run in d3d9 mode, and that won't be the case on xp machines.
To avoid this you'll need to use dynamic linking to call any functions so that the libraries are only loaded at run time. Look up LoadLibrary and GetProcAddress. Luckily with direct3d the only global functions you'll likely call are the "create" functions. D3DX will cause the same issues though
You do understand that DirectX 8 is not supported right? DirectX 10 includes DirectX 9 so there isn't a reason to require both.
You should be able to conditionally include the header files based on what version of DirectX is installed.
Here is an example of how to do exactly that although its written in C#:
How to code to get direct X version on my machine in C#?
The traditional way is install the version of DirectX your application uses when your application is installed. Any other way should be considered a hack and unsupportable in the long-term.
One other comment. What platform do you want to run this on?
Windows vista and newer will run directx11 and directx11 will work on directx9 level hardware (obviously without the newer features like tessalation shaders).
If you don't need to support XP (and it really is getting quite old now...) then forget both dx9 and dx10 and just use directx11