testing const std::string vs enum

Started by
7 comments, last by Burnt_Fyr 10 years, 4 months ago
I've ran into an issue that i'd like some clarification on. In my renderer testing my apps have been switching on a std::string to determine which renderer(dx11 9 or ogl) which works fine if the testing platform is vista or later. However on xp systems without access to the x11 runtimes the app crashes because the dll is not found even when the string indicates the dx9 renderer to be loaded. Using a const bool in a separate test works fine on older systems as long as dx9 is specified. can someone please enlighted me as to the differences in using std::string vs a native type such as bool or int to initialize libraries?
Advertisement

What does using std::string have to do with a dll not being found? Perhaps posting a piece of code could illustrate what you are doing, but these things are completely separate in my mind.

The biggest difference is that you should never, ever, ever, ever, pass an object that is subject to change between builds or compiler versions across dll boundaries. Most especially standard library objects!

Even compiler flags such as whether it is a debug build or not can blow you up, because the object you pass may end up not being the object the dll was built to expect. That might even by why you're crashing (without seeing any code or knowing really what's going on of course).

Also, if you're switching as in a switch statement, and you're testing against strings - it's just comparing pointers cast to integers, not the string itself.

I don't think he's doing anything with DLLs, or better said, not himself. I think he's trying to say that he uses std::string in his app/renderer to determine what to use (DX9/10/11/OpenGL). Because XP doesn't support DX10/11 he gets an error saying the needed DLLs for DX10/11 are not found when he uses that string to determine what he needs, but it seems to work just fine when he uses a const bool.

I think you still include some DX10/11 when using your string, perhaps accidentally. But like mentioned before, it's hard to tell without any relevant code or how you do what you do.

I was on my phone earlier, difficult to post anything coherently.


// top of appmain.cpp

const WCHAR Renderer[] = L"DX9";

//snip

//later on

if(Renderer == L"DX11")
	{
		g_Renderer = new GraphicsEngineDX11(hwnd,600,400);
	}
		
	if(Renderer == L"DX9")
	{
		g_Renderer = new GraphicsEngineDX9(hwnd,600,400);
	}

	if(Renderer == L"GL4")
	{
		g_Renderer = new GraphicsEngineGL4(hwnd,600,400);
	}

This code above crashes on xp systems, compaining that dx11 is not found. but works just fine on win7 systems


const bool d3d11 = false;

//snip

if(d3d11)
	{
		g_Renderer = new GraphicsEngineDX11(hwnd,600,400);
	}
	else	
	{
		g_Renderer = new GraphicsEngineDX9(hwnd,600,400);
	}

This code works on xp and windows vista and later.

The app uses a rendering library that has been created as a static lib in a separate project. The lib contains the classes for each derived renderer. The app chooses which to instantiate based on this test, and is linked against both dx11 and dx9c.

I see a char array here, not an std::string. And that's not how you compare them. Use strcmp or strncmp (or equivalent) or just actually make them std::strings.

I guess it's also possible that in the case of booleans, the compiler ignores the DX11 codepath completely, whereas it doesn't do it in the other case, which causes some initialization code (called regardless of the renderer selection) to fail. But I doubt that.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”

I see a char array here, not an std::string. And that's not how you compare them. Use strcmp or strncmp (or equivalent) or just actually make them std::strings.

I guess it's also possible that in the case of booleans, the compiler ignores the DX11 codepath completely, whereas it doesn't do it in the other case, which causes some initialization code (called regardless of the renderer selection) to fail. But I doubt that.

I was using std::string originally, but I had a hunch that it could have to due with not using a POD, so swapped to const char array instead, but to no avail.

EDIT: I didn't realize that == was not implented with char[] and will now attempt strcmp on the char[]. I do think that it has to do with the compiler treating the string differently than a bool.


This code above crashes on xp systems, compaining that dx11 is not found. but works just fine on win7 systems

The problem I see that is even if you are using a dynamic branch to determine that you are using a DX9-renderer on the XP system, the DX11-one is still present in the lib/exe, and therefore it will demand the dx11-dll. For targeting XP-systems you'll need compile time switching, where you exclude all DX11-related code from compilation:


#define XP_BUILD

#ifndef XP_BUILD
if(Renderer == L"DX11")
	{
		g_Renderer = new GraphicsEngineDX11(hwnd,600,400);
	}
#endif
		
	if(Renderer == L"DX9")
	{
		g_Renderer = new GraphicsEngineDX9(hwnd,600,400);
	}

	if(Renderer == L"GL4")
	{
		g_Renderer = new GraphicsEngineGL4(hwnd,600,400);
	}

I belive the reason why it works in your second code is because d3d11 is a constant, and therefore the compiler will probably determine that new GraphicsEngineDX11 will never be executed and exclude it from the binary file. Does this make it work? Seeing how your char[] is also const, this doesn't make too much sense anymore to me, but I'll leave my post here anyway, maybe it helps though.

Not having a lot of free time today, it took awhile to test with wcscmp and const wchar[] but it is still giving same issue. I'm planning on completely splitting the 3 renderers into separate dlls, based of the same interface which will be stored in the lib linked against my exe, but there seems to be a deeper issue that I'd like solved in the mean time.

This topic is closed to new replies.

Advertisement