EDN Admin
Well-known member
Okay, I have this bizarre problem. When I try to call a virtual function through an interface pointer in C++, it ends up calling the wrong function and then on return I get the Run-Time Check Failure #0. So, heres a simple example, in one function
I call this:
<div style="color:Black;background-color:White; <pre>
canvas->PresentCanvas();
[/code]
(canvas is a pointer to the ICanvas interface and PresentCanvas() is a virtual function)
Here is the ICanvas.h file
<div style="color:Black;background-color:White; <pre>
#pragma once
<span style="color:Blue; namespace hurricane
{
<span style="color:Blue; class <span style="color:Green; /*interface*/ ICanvas
{
<span style="color:Blue; public:
<span style="color:Blue; virtual <span style="color:Blue; int GetWidth() <span style="color:Blue; const = 0;
<span style="color:Blue; virtual <span style="color:Blue; int GetHeight() <span style="color:Blue; const = 0;
<span style="color:Blue; virtual <span style="color:Blue; void ClearCanvas() = 0;
<span style="color:Blue; virtual <span style="color:Blue; void PresentCanvas() = 0;
};
}
[/code]
<br/>
And here is the header of the derived class that provides the functionality:
<div style="color:Black;background-color:White; <pre>
#pragma once
#include <span style="color:#A31515; "GameComponent.h"
#include <Windows.h>
#include <span style="color:#A31515; "IWin32WindowHost.h"
#include <span style="color:#A31515; "ICanvas.h"
#include <span style="color:#A31515; "IDX11GraphicsHost.h"
#include <D3D11.h>
#include <D3DX11.h>
#include <DXGI.h>
<span style="color:Blue; namespace hurricane
{
<span style="color:Blue; class WinDX11GraphicsComponent : <span style="color:Blue; public GameComponent,
<span style="color:Blue; public IWin32WindowHost,
<span style="color:Blue; public ICanvas,
<span style="color:Blue; public IDX11GraphicsHost
{
<span style="color:Blue; private:
HWND _handle;
MSG _msg;
<span style="color:Blue; static WinDX11GraphicsComponent *_globalThis;
RECT _clientRect;
<span style="color:Blue; bool _fullscreen;
ID3D11Device *_device;
ID3D11DeviceContext *_immContext;
ID3D11RenderTargetView *_targetView;
IDXGISwapChain *_swapChain;
WinDX11GraphicsComponent(<span style="color:Blue; const WinDX11GraphicsComponent& other)
: GameComponent((Game*)other.GetGame()) {}
<span style="color:Green; //Helpers that were refactored to cut down on Initialize() code
<span style="color:Blue; void CreateGraphicsWindow();
<span style="color:Blue; void CreateGraphicsDevice();
<span style="color:Green; //Handlers for window messages
<span style="color:Blue; void HandleWMSize(<span style="color:Blue; int sizeParam, <span style="color:Blue; int width, <span style="color:Blue; int height);
<span style="color:Blue; void HandleWMMove(<span style="color:Blue; int x, <span style="color:Blue; int y);
<span style="color:Blue; public:
WinDX11GraphicsComponent(Game *game);
~WinDX11GraphicsComponent();
<span style="color:Green; //IWin32WindowHost
HWND GetHandle() { <span style="color:Blue; return _handle; }
<span style="color:Blue; const HWND GetHandle() <span style="color:Blue; const { <span style="color:Blue; return _handle; }
<span style="color:Green; //IDX11GraphicsHost
ID3D11Device *GetDeviceContext() { <span style="color:Blue; return _device; }
ID3D11DeviceContext *GetImmContext() { <span style="color:Blue; return _immContext; }
<span style="color:Blue; void Initialize();
<span style="color:Blue; void Update(<span style="color:Blue; float deltaT_s);
<span style="color:Green; //ICanvas
<span style="color:Blue; int GetWidth() <span style="color:Blue; const { <span style="color:Blue; return _clientRect.right - _clientRect.left; }
<span style="color:Blue; int GetHeight() <span style="color:Blue; const { <span style="color:Blue; return _clientRect.bottom - _clientRect.top; }
<span style="color:Blue; void ClearCanvas();
<span style="color:Blue; void PresentCanvas();
<span style="color:Blue; bool ImplementsServiceInterface(<span style="color:Blue; const std::wstring &interfaceName);
<span style="color:Blue; static LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam);
};
}
[/code]
<br/>
What happens is, when I call the PresentCanvas() call from the ICanvas *canvas, it ends up actually calling WinDX11GraphicsComponent::Update() which causes some weird behavior with the stack (because no parameter was passed in) and then causes the runtime error
on return. Also, this is what the PresentCanvas() method does:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; void WinDX11GraphicsComponent:resentCanvas()
{
<span style="color:Blue; if(_swapChain != NULL)
{
_swapChain->Present(0, 0);
}
};
[/code]
Just in case this helps, Im compiling 32-bit(x86) here and my project calling convention is __cdecl. Any help is greatly appreciated, thanks in advance.<br/>
<br/>
View the full article
I call this:
<div style="color:Black;background-color:White; <pre>
canvas->PresentCanvas();
[/code]
(canvas is a pointer to the ICanvas interface and PresentCanvas() is a virtual function)
Here is the ICanvas.h file
<div style="color:Black;background-color:White; <pre>
#pragma once
<span style="color:Blue; namespace hurricane
{
<span style="color:Blue; class <span style="color:Green; /*interface*/ ICanvas
{
<span style="color:Blue; public:
<span style="color:Blue; virtual <span style="color:Blue; int GetWidth() <span style="color:Blue; const = 0;
<span style="color:Blue; virtual <span style="color:Blue; int GetHeight() <span style="color:Blue; const = 0;
<span style="color:Blue; virtual <span style="color:Blue; void ClearCanvas() = 0;
<span style="color:Blue; virtual <span style="color:Blue; void PresentCanvas() = 0;
};
}
[/code]
<br/>
And here is the header of the derived class that provides the functionality:
<div style="color:Black;background-color:White; <pre>
#pragma once
#include <span style="color:#A31515; "GameComponent.h"
#include <Windows.h>
#include <span style="color:#A31515; "IWin32WindowHost.h"
#include <span style="color:#A31515; "ICanvas.h"
#include <span style="color:#A31515; "IDX11GraphicsHost.h"
#include <D3D11.h>
#include <D3DX11.h>
#include <DXGI.h>
<span style="color:Blue; namespace hurricane
{
<span style="color:Blue; class WinDX11GraphicsComponent : <span style="color:Blue; public GameComponent,
<span style="color:Blue; public IWin32WindowHost,
<span style="color:Blue; public ICanvas,
<span style="color:Blue; public IDX11GraphicsHost
{
<span style="color:Blue; private:
HWND _handle;
MSG _msg;
<span style="color:Blue; static WinDX11GraphicsComponent *_globalThis;
RECT _clientRect;
<span style="color:Blue; bool _fullscreen;
ID3D11Device *_device;
ID3D11DeviceContext *_immContext;
ID3D11RenderTargetView *_targetView;
IDXGISwapChain *_swapChain;
WinDX11GraphicsComponent(<span style="color:Blue; const WinDX11GraphicsComponent& other)
: GameComponent((Game*)other.GetGame()) {}
<span style="color:Green; //Helpers that were refactored to cut down on Initialize() code
<span style="color:Blue; void CreateGraphicsWindow();
<span style="color:Blue; void CreateGraphicsDevice();
<span style="color:Green; //Handlers for window messages
<span style="color:Blue; void HandleWMSize(<span style="color:Blue; int sizeParam, <span style="color:Blue; int width, <span style="color:Blue; int height);
<span style="color:Blue; void HandleWMMove(<span style="color:Blue; int x, <span style="color:Blue; int y);
<span style="color:Blue; public:
WinDX11GraphicsComponent(Game *game);
~WinDX11GraphicsComponent();
<span style="color:Green; //IWin32WindowHost
HWND GetHandle() { <span style="color:Blue; return _handle; }
<span style="color:Blue; const HWND GetHandle() <span style="color:Blue; const { <span style="color:Blue; return _handle; }
<span style="color:Green; //IDX11GraphicsHost
ID3D11Device *GetDeviceContext() { <span style="color:Blue; return _device; }
ID3D11DeviceContext *GetImmContext() { <span style="color:Blue; return _immContext; }
<span style="color:Blue; void Initialize();
<span style="color:Blue; void Update(<span style="color:Blue; float deltaT_s);
<span style="color:Green; //ICanvas
<span style="color:Blue; int GetWidth() <span style="color:Blue; const { <span style="color:Blue; return _clientRect.right - _clientRect.left; }
<span style="color:Blue; int GetHeight() <span style="color:Blue; const { <span style="color:Blue; return _clientRect.bottom - _clientRect.top; }
<span style="color:Blue; void ClearCanvas();
<span style="color:Blue; void PresentCanvas();
<span style="color:Blue; bool ImplementsServiceInterface(<span style="color:Blue; const std::wstring &interfaceName);
<span style="color:Blue; static LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam);
};
}
[/code]
<br/>
What happens is, when I call the PresentCanvas() call from the ICanvas *canvas, it ends up actually calling WinDX11GraphicsComponent::Update() which causes some weird behavior with the stack (because no parameter was passed in) and then causes the runtime error
on return. Also, this is what the PresentCanvas() method does:
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; void WinDX11GraphicsComponent:resentCanvas()
{
<span style="color:Blue; if(_swapChain != NULL)
{
_swapChain->Present(0, 0);
}
};
[/code]
Just in case this helps, Im compiling 32-bit(x86) here and my project calling convention is __cdecl. Any help is greatly appreciated, thanks in advance.<br/>
<br/>
View the full article