dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: OpenGL Glew fails to keep Initialization across dlls and client exe application!

  1. #1
    Join Date
    Jul 2017
    Posts
    78

    OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Hello!

    I have a problem when I'm trying to call GL calls. I get memory access violation. I know that this error is usually occurs if you haven't initialize GLEW or any other OpenGL function retriever library correctly and you didn't get the function pointers but I'm 100% sure I'm initializing glew. Since I know I initialized glew, the problem must be with the dll.

    I thing the problem is happening because I'm hiding the glfw and the gl calls inside a .dll and then use that in a Client app. Let me tell you briefly what is happening in my code.

    The client is including a Window.h library that has the library implementation in c++ classes hardcoded. The client is creating a Window instance which the constructor is calling an extern "C" function which initializes GLFW and GLEW. After that, the client is calling another extern "C" function which instantiates a c++ class called Renderer which calls gl call functions, and there is where I get the access violation error. The Renderer.cpp and the Window.cpp which contains the GLFW and GLEW initialization code where compiled from the same project into a .dll. Also I'm linking GLEW and GLFW dynamicly to my .dll project.

    I found on the internet these messages:
    -Glew uses statics, so you need to call glewInit in each of your DLLs as well as your main app. Make sure the GL context is active when you do.
    The reason I'm hiding GLFW and gl calls inside a dll is to prevent the Client to compile and link against GLFW and GLEW. So if i have to Init glew in the client code to
    then there is no point of what I'm doing, since the Client will have to link against GLEW in order to call glewInit().

    -If I remember correctly, OpenGL contexts are thread-local. That's what wgl/glXMakeCurrent does. So you might encounter problems if you make your context current on one thread, but execute the OpenGL calls in another thread. Other than that, separating the code into libraries shouldn't make a difference.

    -Make sure you're linking them both with the same c runtimes.. or they won't share a heap, and then also read the post here about resolving the linking later.
    Do you know what is the problem?

    If you want to see I will also post the dll code. The structure goes like this:
    1) The client is inheriting an VampApp class and defines an entry point.
    2) The entry point is instantiating a VampApp instance.
    3) The VampApp instance creates a Core object.
    4) That core object is creating a Window.
    5) The window is calling extern "c" functions to initialize GLEW and GLFW.
    6) The core object is calling an extern "C" funtion to create a Renderer object.
    7) Inside the constructor of the Renderer gl calls are failing due to access violation.

    Window.h
    Code:
    #ifndef VAMP_ENGINE_WINDOW_H
    #define VAMP_ENGINE_WINDOW_H
    #include <iostream>
    #include "ExportDLL.h"
    #include "EngineError.h"
    
    //GLFWwindow Decleration.
    extern "C" struct GLFWwindow;
    
    
    
    
    extern "C" 
    {
    
    	///WindowImpl Struct.
    	/**
    	You SHOULD NOT instantiate an instance of this Struct!
    	The VampEngine::VampApp handle's instances of this Struct
    	automatically. Also you SHOULD NOT read/write members of it.
    	*/
    	struct WindowImpl
    	{
    		GLFWwindow *m_GLFWwindow;
    		const char *m_Error;
    		const char *m_Title;
    		int m_Width, m_Height;
    	};
    
    	//WindowImpl Class Functions.
    
    	///InitializeWindowImpl Extern Func.
    	/**
    	DO NOT call this function. This is part of the VampEngine system.
    	*/
    	VAMP_ENGINE_EXPORT int InitializeWindowImpl(struct WindowImpl *window, const char *title, unsigned int width, unsigned int height);
    
    	///DestroyWindowImpl Extern Func.
    	/**
    	DO NOT call this function. This is part of the VampEngine system.
    	*/
    	VAMP_ENGINE_EXPORT int DestroyWindowImpl(struct WindowImpl *window);
    }
    
    
    
    
    namespace VampEngine
    {
    	//-_-_-_-_-_-_-_-_-_-Declarations-_-_-_-_-_-_-_-_-_-//
    
    	//Classes.
    
    	//-_-_-_-_-_-_-_-_-_-Declarations-_-_-_-_-_-_-_-_-_-//
    
    	///Window Class.
    	/**
    	You SHOULD NOT instantiate an instance of this class!
    	The VampApp handle's instances of this class
    	automatically.
    	*/
    	class Window
    	{
    
    		//Friends.
    		friend class Core;
    
    	//Private Members.
    	private:
    
    		WindowImpl *m_PtrToImpl;
    
    
    
    	//Public Methods.
    	public:
    
    		///Constrcutor.
    		Window(std::string title, unsigned int width, unsigned int height)
    		{
    			//Create and initialize the Window.
    			m_PtrToImpl = new WindowImpl();
    			int error   = InitializeWindowImpl(m_PtrToImpl, title.c_str(), width, height);
    
    			//Initialization Failed.
    			if (error) throw EngineError(m_PtrToImpl->m_Error);
    		}
    
    		///Deconstructor.
    		~Window() 
    		{
    			//Destroy the implementation.
    			DestroyWindowImpl(m_PtrToImpl);
    		}
    
    		///GetWidth() Method.
    		/**
    		Return's the width of the window.
    		*/
    		inline int GetWidth() { return m_PtrToImpl->m_Width; }
    
    		///GetHeight() Method.
    		/**
    		Return's the height of the window.
    		*/
    		inline int GetHeight() { return m_PtrToImpl->m_Height; }
    
    		///GetTitle() Method.
    		/**
    		Return's the title of the window.
    		*/
    		inline std::string GetTitle() { return m_PtrToImpl->m_Title; }
    
    	};
    }
    
    #endif

    Window.cpp
    Code:
    #include "Window.h"
    #include "glcall.h"
    #include <GLFW/glfw3.h>
    #include "Logger.h"
    
    
    //Constructor.
    int InitializeWindowImpl(struct WindowImpl *window, const char *title, unsigned int width, unsigned int height)
    {
    
    	//----------Initialize----------//
    	window->m_Error  = "";
    	window->m_Width  = width;
    	window->m_Height = height;
    	window->m_Title  = title;
    
    	/* Initialize the library */
    	if (!glfwInit())
    	{
    		window->m_Error = "GLFW failed to be initialized.";
    		return 1;
    	}
    
    	//OpenGL Version 3.3 Core Profile.
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
    	/* Create a windowed mode window and its OpenGL context */
    	window->m_GLFWwindow = glfwCreateWindow(width, height, title, NULL, NULL);
    	if (!window->m_GLFWwindow)
    	{
    		window->m_Error = "GLFW failed to create a Window.";
    		glfwTerminate();
    		return 1;
    	}
    
    	/* Make the window's context current */
    	glfwMakeContextCurrent(window->m_GLFWwindow);
    
    	//Initialize Glew.
    	if (glewInit() != GLEW_OK)
    	{
    		window->m_Error = "GLEW failed to be initialized.";
    		glfwDestroyWindow(window->m_GLFWwindow);
    		glfwTerminate();
    		return 1;
    	}
    
    	//Set Viewport.
    	glViewport(0, 0, width, height);
    
    	//Succeeded.
    	return 0;
    }
    
    
    
    
    //Deconstructor.
    int DestroyWindowImpl(struct WindowImpl *window)
    {
    
    	//Destroy GLFW Window.
    	glfwDestroyWindow(window->m_GLFWwindow);
    
    	//Terminate GLFW.
    	glfwTerminate();
    
    	//Delete the window.
    	delete window;
    
    	//Succeeded.
    	return 0;
    }
    Core.h:
    Code:
    #ifndef VAMP_ENGINE_CORE_H
    #define VAMP_ENGINE_CORE_H
    #include "Window.h"
    #include "EngineError.h"
    #include "ExportDLL.h"
    
    //Class Declerations//
    class Renderer;
    
    
    extern "C"
    {
    
    	///CoreImpl Struct.
    	/**
    	You SHOULD NOT instantiate an instance of this Struct!
    	The VampEngine::Core handle's instances of this Struct
    	automatically.
    	*/
    	struct CoreImpl
    	{
    		const char *m_Error;
    		Renderer   *m_Renderer;
    	};
    
    
    	VAMP_ENGINE_EXPORT int MainLoopImpl(struct WindowImpl *window, struct CoreImpl *core);
    	VAMP_ENGINE_EXPORT int InitializeCoreImpl(struct CoreImpl *core);
    	VAMP_ENGINE_EXPORT int DestroyCoreImpl(struct CoreImpl *core);
    }
    
    
    namespace VampEngine
    {
    
    	//-_-_-_-_-_-_-_-_-_-Declarations-_-_-_-_-_-_-_-_-_-//
    
    	//Classes.
    	class Window;
    	class Input;
    
    	//Functions.
    	//-_-_-_-_-_-_-_-_-_-Declarations-_-_-_-_-_-_-_-_-_-//
    
    	///Core Class.
    	/**
    	You SHOULD NOT instantiate an instance of this class!
    	The VampApp handle's instances of this class
    	automatically.
    	*/
    	class Core
    	{
    
    	//Private Members.
    	private:
    		CoreImpl *m_PtrToImpl;
    		Window   *m_Window;
    		Input    *m_Input;
    		float     m_Time;
    		int       m_FPS;
    
    
    	//Public Methods.
    	public:
    
    		///Constrcutor.
    		Core(std::string title, unsigned width, unsigned height) 
    		{
    
    			//Create the Implementation.
    			m_PtrToImpl = new CoreImpl();
    			InitializeCoreImpl(m_PtrToImpl);
    
    
    			//Create a new Window.
    			m_Window = new Window(title, width, height);
    		}
    
    		///Deconstructor.
    		~Core() 
    		{
    			DestroyCoreImpl(m_PtrToImpl);
    
    			delete m_Window;
    		}
    
    		///GetWindow() Method.
    		/**
    		Use this method to get a refernce of the Window object.
    		Use that object to get info like the size of the window
    		or make changes to it.
    		*/
    		inline Window *GetWindow() { return m_Window; }
    
    		///GetInput() Method.
    		/**
    		Use this method to get a refernce of the Input object.
    		Use that object to get input from the keyboard or the mouse.
    		*/
    		inline Input *GetInput() { return m_Input; }
    
    		///GetTime() Method.
    		/**
    		Return's the time in seconds, since the Application
    		has started.
    		*/
    		inline float GetTime() { return m_Time; }
    
    		///GetFPS() Method.
    		/**
    		Return's the FPS of the Application.
    		*/
    		inline int GetFPS() { return m_FPS; }
    
    		///MainLoop() Method.
    		/**
    		You SHOULD NOT MESS with this method. The VampApp
    		handle's it.
    		*/
    		void MainLoop()
    		{ 
    
    			//Call MainLoop.
    			int error = MainLoopImpl(m_Window->m_PtrToImpl, m_PtrToImpl);
    
    			//If an error occur, throw an exception.
    			if (error) throw EngineError(m_Window->m_PtrToImpl->m_Error);
    		}
    
    
    	};
    }
    
    #endif

    Core.cpp:

    Code:
    #include "Core.h"
    #include "Renderer.h"
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    
    int MainLoopImpl(struct WindowImpl *window, struct CoreImpl *core)
    {
    
    	/* Loop until the user closes the window */
    	while (!glfwWindowShouldClose(window->m_GLFWwindow))
    	{
    		/* Render here */
    		glClear(GL_COLOR_BUFFER_BIT);
    
    		//core->m_Renderer->RenderElements();
    
    		/* Swap front and back buffers */
    		glfwSwapBuffers(window->m_GLFWwindow);
    
    		/* Poll for and process events */
    		glfwPollEvents();
    	}
    
    	return 0;
    }
    
    
    
    
    //Core Implementation Constructor.
    int InitializeCoreImpl(struct CoreImpl *core)
    {
    	core->m_Error    = "";
    	core->m_Renderer = new Renderer();
    
    	return 0;
    }
    
    
    
    //Core Implementation Deconstructor.
    int DestroyCoreImpl(struct CoreImpl *core)
    {
    	delete core->m_Renderer;
    	delete core;
    
    	return 0;
    }

    Renderer.h
    Code:
    #ifndef VAMP_ENGINE_RENDERER_H
    #define VAMP_ENGINE_RENDERER_H
    
    class Shader;
    
    class Renderer
    {
    
    private:
    
    	unsigned int VAO, VBO, EBO;
    
    	Shader *m_shader;
    
    public:
    
    	Renderer();
    	~Renderer();
    
    	void RenderElements();
    
    };
    #endif

    Renderer.cpp:
    Code:
    #include "Renderer.h"
    #include "glcall.h"
    #include "shader.h"
    #include <GLM/glm.hpp>
    #include <GLM/gtc/matrix_transform.hpp>
    
    
    Renderer::Renderer()
    {
    
    	//Vertices.
    	float vertices[] =
    	{
    
    		//Positions    Texture Coordinates.
    
    		0.0f, 0.0f,    0.0f, 0.0f, //Left Bottom.
    		0.0f, 1.0f,    0.0f, 1.0f, //Left Top.
    		1.0f, 1.0f,    1.0f, 1.0f, //Right Top.
    		1.0f, 0.0f,    1.0f, 0.0f  //Right Bottom.
    	};
    
    	//Indices.
    	unsigned int indices[] = 
    	{
    		0, 1, 2, //Left Up Triangle.
    		0, 3, 2  //Right Down Triangle.
    	};
    
    	glCreateProgram();
    	
    	/*
    	//Create and bind a Vertex Array.
    	GLCall(glGenVertexArrays(1, &VAO));
    	GLCall(glBindVertexArray(VAO));
    
    	
    	//Create and bind a Vertex Buffer.
    	GLCall(glGenBuffers(1, &VBO));
    	GLCall(glBindBuffer(GL_ARRAY_BUFFER, VBO));
    
    	//Create and bind an Index Buffer.
    	GLCall(glGenBuffers(1, &EBO));
    	GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO));
    
    	//Transfer the data to the VBO and EBO.
    	GLCall(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
    	GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
    
    	//Enable and create the attribute for both Positions and Texture Coordinates.
    	GLCall(glEnableVertexAttribArray(0));
    	GLCall(glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, (void *)0));
    
    	//Create the shader program.
    	m_shader = new Shader("Shaders/sprite_vertex.glsl", "Shaders/sprite_fragment.glsl");
    	*/
    }
    
    
    Renderer::~Renderer()
    {
    	//Clean Up.
    	GLCall(glDeleteVertexArrays(1, &VAO));
    	GLCall(glDeleteBuffers(1, &VBO));
    	GLCall(glDeleteBuffers(1, &EBO));
    	delete m_shader;
    }
    
    
    
    void Renderer::RenderElements()
    {
    
    	glm::mat4 model = glm::mat4(1.0f);
    	model = glm::scale(model, glm::vec3(20.0f, 20.0f, 1.0f));
    
    	glm::mat4 proj = glm::ortho(0.0f, 600.0f, 600.0f, 0.0f, -1.0f, 1.0f);
    
    	m_shader->SetUniform1i("diffuse", 0);
    
    	m_shader->SetUniformMat4f("model", model);
    	m_shader->SetUniformMat4f("proj", proj);
    
    	//Draw Call.
    	GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL));
    }

    Application Class (Is getting inherited by the client):
    Code:
    #ifndef VAMP_ENGINE_VAMP_APP
    #define VAMP_ENGINE_VAMP_APP
    #include <iostream>
    #include "Core.h"
    #include "Logger.h"
    
    namespace VampEngine
    {
    
    	///VampApp Class.
    	/**
    	Inherit this class to create a Vamp Application.
    	YOU ALSO HAVE to implement the function VampEngine::CreateVampApp
    	in order to return an instance of your Application.
    	*/
    	class VampApp
    	{
    
    	//Public Members.
    	public:
    
    		Core * const core;
    
    	//Public Methods.
    	public:
    
    		///Constructor.
    		VampApp(std::string title, unsigned int width, unsigned int height) 
    			: core(new Core(title, width, height))
    		{
    		}
    
    		///Deconstructor.
    		virtual ~VampApp()
    		{
    			delete core;
    		}
    	};
    }
    
    #endif

    Client's Entry Point:
    Code:
    #define VAMP_ENGINE_ENTRY_POINT
    #include <VampEngine.h>
    
    #ifdef VAMP_ENGINE_ENTRY_POINT
    
    
    #include "VampApp.h"
    #include <iostream>
    
    namespace VampEngine
    {
    	///VampApp Funtion.
    	/**
    	YOU MUST implement this function to return
    	an instance of your VampApp class. Don't forget to
    	define VAMP_ENGINE_ENTRY_POINT before you include 
    	VampEngine.h in order to enable this function and
    	the entry point of your application.
    	*/
    	VampApp *CreateVampApp();
    }
    
    
    ///main Funtion.
    /**
    This is the main function of your VampEngine::VampApp.
    YOU MUST define VAMP_ENGINE_ENTRY_POINT in ONLY ONE
    .cpp file, to get this entry point function.
    */
    int main(int argc, char *argv[])
    {
    	VampEngine::VampApp *app = VampEngine::CreateVampApp();
    	app->core->MainLoop();
    	delete app;
    
    	//On Debug Mode Pause the console before exiting.
    	#ifdef _MSC_BUILD
    	#	ifdef _DEBUG
    			std::cout << "Press ENTER to exit..." << std::endl;
    			std::cin.get();
    	#	endif
    	#else
    	#	ifdef VAMP_ENGINE_LINUX_DEBUG
    			std::cout << "Press ENTER to exit..." << std::endl;
    			std::cin.get();
    	#	endif
    	#endif
    }
    #endif
    
    class MyApp : public VampEngine::VampApp
    {
    public:
    
    	MyApp()
    		: VampApp("Test", 600, 600)
    	{
    	}
    };
    
    
    VampEngine::VampApp *VampEngine::CreateVampApp()
    {
    	return new MyApp();
    }

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,516

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    As I've never used OpenGL, I can't comment on that. However from a .dll point of view memory allocated in a .dll needs to be freed/deleted in the same .dll and memory allocated in an .exe needs to be freed/deleted in the exe. Allocating in a .dll and deleting in .exe or allocating in an .exe and deleting in a .dll is a no-no (one more for your collection!). Memory allocated in .dll can be used OK in an .exe and vice-versa - but the allocation/deletion needs to be in the same .exe or .dll.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.4)

  3. #3
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Quote Originally Posted by 2kaud View Post
    As I've never used OpenGL, I can't comment on that. However from a .dll point of view memory allocated in a .dll needs to be freed/deleted in the same .dll and memory allocated in an .exe needs to be freed/deleted in the exe. Allocating in a .dll and deleting in .exe or allocating in an .exe and deleting in a .dll is a no-no (one more for your collection!). Memory allocated in .dll can be used OK in an .exe and vice-versa - but the allocation/deletion needs to be in the same .exe or .dll.
    Yes, the allocation of GLEW is happening only on the dll. The client just calls extern functions that does this job, and don't mess with any GLEW code. The thing is that the problem is getting caused inside the dll itself.

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,516

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    It seems that now is a good time to practice your .dll debugging skills!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.4)

  5. #5
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Quote Originally Posted by 2kaud View Post
    It seems that now is a good time to practice your .dll debugging skills!
    I think I have no clue how to do that

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,516

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Quote Originally Posted by babaliaris View Post
    I think I have no clue how to do that
    See https://docs.microsoft.com/en-us/vis...s?view=vs-2017
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.4)

  7. #7
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    OMG I'm so dump!!! I was calling the function that handles gl calls before I run the function that initialize GLEW Shame on me.
    Anyway problem solved. And I've done this before a lot of times when I was learning graphics api's hahaha , still I'm falling for it.

    The problem was here:
    Core.h Constructor.
    Code:
    		///Constrcutor.
    		Core(std::string title, unsigned width, unsigned height) 
    		{
    
    			//Create the Implementation.
    			m_PtrToImpl = new CoreImpl();
    			InitializeCoreImpl(m_PtrToImpl);
    
    
    			//Create a new Window.
    			m_Window = new Window(title, width, height);
    		}
    InitializeCoreImpl must be called after the Window creation, because the window constructor is Initializing the function pointers of OpenGL which I'm using inside the InitializeCoreImpl function.
    Last edited by babaliaris; December 6th, 2018 at 01:08 PM.

  8. #8
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Can you tell me what causes this debug error below? I have encountered it a lot of times and don't know what it means.

    Name:  Capture.PNG
Views: 74
Size:  11.6 KB

    This is where it occurs:
    Name:  Capture2.jpg
Views: 74
Size:  20.5 KB

    You can also read the code here (it occurs in the free(data) ):
    Code:
    static void ReadSources(std::string filename, bool is_vertex, struct ShaderSource *src)
    {
    
    	//Create a file object.
    	std::ifstream file;
    
    	//Open the file.
    	file.open(filename, std::ios::in);
    
    	//If the file opened successfully read it.
    	if (file.is_open())
    	{
    
    		//Size of the file.
    		file.seekg(0, std::ios::end);
    		std::streampos size = file.tellg();
    		file.seekg(0, std::ios::beg);
    
    		//Allocate memory to store the data.
    		char *data = (char *)malloc(sizeof(char) * size );
    
    		//Read the data from the file.
    		file.read(data, size);
    
    		//Close the string.
    		data[file.gcount()] = '\0';
    
    		//Close the file.
    		file.close();
    
    		//This was the vertex file.
    		if (is_vertex)
    			src->vertex_src = (const char *)data;
    
    		//This was the fragment file.
    		else
    			src->fragment_src = (const char *)data;
    
    		//Release the memory for the data since I coppied them into the ShaderSource structure.
    		free(data);
    	}
    
    
    	//Problem opening the file.
    	else
    		throw VampEngine::EngineError("There was a problem opening the file: " + filename);
    }
    Attached Images Attached Images  
    Last edited by babaliaris; December 6th, 2018 at 01:20 PM.

  9. #9
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    By the way It was fixed when I changed the code:
    Code:
    //Allocate memory to store the data.
    char *data = (char *)malloc(sizeof(char) * size );
    To:
    Code:
    //Allocate memory to store the data.
    char *data = (char *)malloc(sizeof(char) * (size+(std::streampos)1) );

  10. #10
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,516

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Can you tell me what causes this debug error below?
    Probably because you are causing a buffer overflow error by writing past end of allocated memory.

    Code:
    data[file.gcount()] = '\0';
    looks a likely candidate. If say the size of the file is 1, then you allocate one byte and read one byte into the allocated memory. OK. As you're read 1 byte, then gcount() will return 1 so data[1] is set to 0 - which is outside of the allocated memory (1 byte so only data[0] is valid). So you need to add 1 to size for the memory allocation.

    Note that in c++ you don't use malloc() and free(), you use new and delete. Or even better unique_ptr. See http://www.cplusplus.com/reference/memory/unique_ptr/ With unique_ptr you don't need to remember to free the memory - it will automatically be freed when the variable goes out of scope.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.4)

  11. #11
    Join Date
    Jul 2017
    Posts
    78

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Quote Originally Posted by 2kaud View Post
    Probably because you are causing a buffer overflow error by writing past end of allocated memory.
    Note that in c++ you don't use malloc() and free(), you use new and delete. Or even better unique_ptr. See http://www.cplusplus.com/reference/memory/unique_ptr/ With unique_ptr you don't need to remember to free the memory - it will automatically be freed when the variable goes out of scope.
    I was trying to use unique_ptr but the method file.read() doesn't accept it. To I have to to call a method from the unique_ptr object to return a raw pointer? I don't really know how to use these kind of c++ things like smart pointers, c++ way of typecasting and more, templates (i know how to use them but not how to make them)...

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,516

    Re: OpenGL Glew fails to keep Initialization across dlls and client exe application!

    Consider (not tried)

    Code:
    	//Create a file object.
    	std::ifstream file(filename);
    
    	//If the file opened successfully read it.
    	if (file.is_open()) {
    
    		//Size of the file.
    		file.seekg(0, std::ios::end);
    		auto size = file.tellg();
    		file.seekg(0, std::ios::beg);
    
    		//Allocate memory to store the data.
    		auto data = std::make_unique<char[]> (1 + size);
    
    		//Read the data from the file.
    		file.read(data.get(), size);
    
    		//Close the string.
    		data[file.gcount()] = '\0';
    
    		//Close the file.
    		file.close();
    
    		//This was the vertex file.
    		if (is_vertex)
                    	src->vertex_src = data.get();
    
    		//This was the fragment file.
    		else
    			src->fragment_src = data.get();
    	}
            else
               ....
    NB. You should get into the habit of using the c++ casts rather than the c style casts. See https://en.cppreference.com/w/cpp/language/static_cast for static_cast and the See Also at the bottom for the other ones.
    Last edited by 2kaud; December 7th, 2018 at 09:53 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.9.4)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)