Sign in to follow this  
zyrolasting

Finding pointers to data throughtout multiple sources

Recommended Posts

zyrolasting    280
I'm trying to access data in structures, but since I am using a wrapper it becomes annoying to continue adding parameters to accommodate finding them. How can I write a function that gives me the address of a struct/class instance or whatever with the instance of interest not visible in the source I'm working in?

Share this post


Link to post
Share on other sites
zyrolasting    280
Quote:
Huh?


Please tell me what you don't understand about my question, I'm sure you know that didn't get us anywhere.

If I could rephrase: I'm just trying to get the address of, well, anything when it's not visible in a source file out of many in a wrapper for an app.
For example, I recall seeing a function on MSDN that returns a pointer to a hWnd value.

For the record, is there something obvious I'm missing that just made me look dumb? If so, please let me know anyway. I'm still getting accustomed to the architecture of these apps. I do have the feeling I am missing something painfully obvious, but I can't put my finger on it.

Share this post


Link to post
Share on other sites
ToohrVyk    1595
Quote:
Original post by zyrolasting
If I could rephrase: I'm just trying to get the address of, well, anything when it's not visible in a source file out of many in a wrapper for an app.
I have trouble understanding what you mean by "not visible". Do you mean that there is an application which manipulates a value, but that value is not accessible from the outside?

If you can control the application source code, then you could just make the value "visible" by changing the code.

If you can't control the application source code, then you don't have many choices beyond just exploring the memory of the running application. If you're lucky, the instance is a global that is always loaded at the same location in memory, so you can just look for it there. If you're not lucky, the instance is allocated dynamically at runtime, meaning that its address can change every time. You can either find a chain of pointers leading from a known global variable to that value and follow that chain, or you can search the application memory space for a value with a specific in-memory pattern (if there is a recognizable pattern to begin with).

Of course, accessing values that an application chooses not to make visible is brittle, and will usually stop working for other versions of the application.

Or did you mean that you need a variable defined in another header file? If so, just include the header file.

Quote:
For example, I recall seeing a function on MSDN that returns a pointer to a hWnd value.
I don't follow you. There are functions on MSDN that return integers, too. What does this have to do with non-visible values?

Share this post


Link to post
Share on other sites
mmakrzem    1036
I don't think I fully understand your question either. If you create a class that has all your data inside it (be it variables or structures), if you declaire them as public then you can have access to them from where ever.

Share this post


Link to post
Share on other sites
zyrolasting    280
Sure thing. First, I'll mention what I mean by "not visible".
I'm speaking more in the sense of an instance (class/struct) is not in the scope of a source. Yeah, I see how that's vague. My apologies.

I have a class that defines the attributes for a game window (Forgive primitive coding style, refining as I go)


class GameWindow
{
HWND hWnd;
HINSTANCE hInst;
LPTSTR title;
int Width, Height;
bool Windowed;
public:
GameWindow()
{
hWnd = NULL;
title = L"DX Practice";
Width = 1024;
Height = 768;
Windowed = false;
}

//Function: Set Dimensions.
//Sets the screen dimensions to a common ratio based on preset.
void setDimensions(int preset)
{
if (preset > 2) return;
switch (preset)
{
case 0:
Width = 640;
Height = 480;
break;
case 1:
Width = 800;
Height = 600;
break;
case 2:
Width = 1024;
Height = 768;
break;
}
}
void ToggleFullscreen(bool full)
{
Windowed = full;
}
bool getWindowed()
{
return Windowed;
}

};











Needless to say, it's important that I have an instance of this available to me
whenever it needs changing. The problem I have that's causing me to ask what I ask is that I have multiple source files that make a wrapper, and the instance that is used when registering my window class in in the source that handles WinAPI calls.

Once I get to my game loop (This is a DirectX app) I want to be able to change some attributes of the instance by keystroke. (I.E. Windowed)
This code handled in the loop is in another source, and the instance will not be recognized there. The struct is known, but not the instance. That was defined elsewhere. It doesn't even matter if it's global in the other source. (but I think what I'm hearing from Toohr is that's not supposed to happen. No clue what to say there... This is just my case.)

I know that I could just pass it. I'm fully aware of that. But as I stated in the original post, it got tiring moving about the wrapper and redefining all my functions.

So, I wanted to find a way to get a pointer to my instance using a function knowing this scenario. I figured I'd something with the this keyword and toss it in the class, but even so I'd need to access the instance to even run it.

When I mentioned that hWnd function, I was running off hazy memory but I do believe I am seen functions designed to return pointers for this reason.

Please don't tell me it's impossible after all that! =P
If it is, are there any methods that would help?

Let me know if I'm still too vague somewhere.

Share this post


Link to post
Share on other sites
Mathmo    163
Assuming we are talking c++ here, runtime behaviour like this is not really intended... If I understand what you are asking, for example from some of my code:


// "Proprietary library source code"
/* TPZ Core Engine DLL - Core module contains core API functionality for
the Topaz(c) engine, handles memory allocation, message handling and loading
of supplementary satellites to handle extra functionality
All code and design copyright 2008 Mark Brand - mark.brand@lincoln.ox.ac.uk*/


#ifndef TPZ_CE_MEMMANAGER_H
#define TPZ_CE_MEMMANAGER_H

#ifdef TPZ_MEM_EXPORTS
#define TPZ_MEM_API __declspec(dllexport)
#else
#define TPZ_MEM_API __declspec(dllimport)
#endif // TPZ_MEMMANAGER_EXPORTS

///////////////////////////
// INCLUDES
///////////////////////////

#ifndef NDEBUG // DEBUG INCLUDES
#include <vector>
#include <map>
#endif // NDEBUG


///////////////////////////
// MEMMANAGER DECLARATION
///////////////////////////

#ifndef NDEBUG // DEBUG VERSION

//#define TPZ_ALLOC_LOGGING

struct ALLOC_INFO
{
size_t m_size;
char* m_file;
int m_line;

ALLOC_INFO()
{ m_size = 0; m_file = 0; m_line = 0; }
};

class MemManager
{
private:

int m_threads;
static MemManager* m_globalMemManager;

static std::map< void*, ALLOC_INFO >* m_openAllocs;

public:

MemManager();
~MemManager();

static MemManager* GetMemManager()
{ return m_globalMemManager; }

static void* Allocate( size_t, char*, int );
static void Deallocate( void* );
static void Clear();
};

#else // RELEASE VERSIONS

class MemManager
{
private:

int m_threads;
static MemManager* m_globalMemManager;

public:

MemManager();
~MemManager();

static MemManager* GetMemManager()
{ return m_globalMemManager; }

static void* Allocate( size_t, char*, int );
static void Deallocate( void* );
};

#endif // NDEBUG

TPZ_MEM_API void* MemAllocate( size_t size, char* file, int line );
TPZ_MEM_API void MemDeallocate( void* ptr );

#endif // TPZ_CE_MEMMANAGER_H




which is then compiled into a .dll
and you want to do something like


// main.cpp

void loadDll();
MemManager* magicallyGetReferenceToMemManager();
// which would get me a reference to the instance of MemManager
// which the .dll creates, and which the designer of the library
// did not intend for you to use.

int main()
{
loadDll();
MemManager* haxxoredMemManager = magicallyGetReferenceToMemManager();
}




can you think of any cases in which this is a good idea?
What happens if this was possible and you had several other loaded modules using your memorymanager, and you "delete" it - given that you have overridden delete with the call of a memory manager function?

Unless you are talking about this instead


MyStruct.h

struct MyStruct
{
std::Vector< std::Vector< int > > importantData;
};





MyWrapper.h
#include "MyStruct.h"

Class MyStructStore
{
std::map< MyStruct, String > database;

public:
// while you can do this, and keep changing it as your stored data changes
int getImportantData(String key, int dataIndex1, int dataIndex2)
{
return database.get(key).get(dataIndex1).get(dataIndex2);
}

// you could equally do
const MyStruct& getImportantData(String key)
{
return &database.get(key)
}
};




hope I managed to understand what you are after with one of those -if not can you give more details:
what wrapper? one you wrote? what form is it in? precompiled binary .dll, .lib or source?
What access do you need to the data? how is the data stored?

Mathmo

EDIT: Ninja'd.

I see what you want to do now. You have a global instance of something, and you want to access it from everywhere in your code unconditionally. RIGHT? Then we do this


MyGlobalClassThingy.h

MyClass* instance = new MyClass(args);

inline MyClass* GetMyClass()
{
return instance;
}

inline CleanTheFrackUp()
{
if (instance)
{
instance->CleanUp();
delete instance;
instance = 0;
}
}



but that is pretty bad design. Think it would do the trick though. But it is also a very bad idea, because think of what happens if you do this:


int main()
{
MyClass* inst = GetMyClass();
delete inst;
inst = GetMyClass();
inst->foo();
}



There is a far better way to do this - look up singletons. But then, of course you have a singleton. I used to think this was essential, but then I saw the light.
What I would do is if it so essential for all of your classes in your wrapper to use it, then just put an argument in each of their constructors and within each instance of one of your wrapper classes store a pointer to this globally used instance. It may look a little ugly at first, but it IS better than the actual global instance idea.

Share this post


Link to post
Share on other sites
stonemetal    288
Quote:
Original post by zyrolasting

Needless to say, it's important that I have an instance of this available to me
whenever it needs changing. The problem I have that's causing me to ask what I ask is that I have multiple source files that make a wrapper, and the instance that is used when registering my window class in in the source that handles WinAPI calls.

So, I wanted to find a way to get a pointer to my instance using a function knowing this scenario. I figured I'd something with the this keyword and toss it in the class, but even so I'd need to access the instance to even run it.



use the extern keyword to make your global available across translation units, or pass it around from where it is created to where it is needed.

Share this post


Link to post
Share on other sites
krez    443
Maybe I misunderstand, but it sounds to me like you just need to declare it as extern in the source files you want to use it in. This will allow it to use the instance from another translation unit.

(EDIT: Ah I typed too slow)

Share this post


Link to post
Share on other sites
zyrolasting    280
Quote:

There is a far better way to do this - look up singletons. But then, of course you have a singleton. I used to think this was essential, but then I saw the light.
What I would do is if it so essential for all of your classes in your wrapper to use it, then just put an argument in each of their constructors and within each instance of one of your wrapper classes store a pointer to this globally used instance. It may look a little ugly at first, but it IS better than the actual global instance idea.


Gotcha. I am looking at singletons, and it may take me a bit to completely understand them. I guess I'll head back to tossing my instances about parameters until then. Many Thanks.

Share this post


Link to post
Share on other sites
jyk    2094
Quote:
Gotcha. I am looking at singletons, and it may take me a bit to completely understand them.
I'm not sure that post was intended to encourage the use of singletons (although I could be wrong about that).

In any case, IMO, a singleton is the last thing you need right now (if ever). If you really need global access to an object, just make the object globally visible; using extern is a fairly typical way to achieve this. Of course there are usually alternatives to making an object globally visible, and those alternatives are generally to be preferred.

Share this post


Link to post
Share on other sites
zyrolasting    280
For the sake of simplicity and a quick solution I would use extern, but even so it always helps to learn about new topics.

Speaking of which, other than singleton can you say what "alternatives" do you mean?
Aiming for a novice-intermediate user here.

Thanks for all the help guys.

Share this post


Link to post
Share on other sites
chairthrower    440
Quote:
Once I get to my game loop (This is a DirectX app) I want to be able to change some attributes of the instance by keystroke. (I.E. Windowed)
This code handled in the loop is in another source, and the instance will not be recognized there. The struct is known, but not the instance. That was defined elsewhere. It doesn't even matter if it's global in the other source. (but I think what I'm hearing from Toohr is that's not supposed to happen. No clue what to say there... This is just my case.)


Very generally you need to establish a means of using callback handlers. The handler enables you to be able register actions (methods on the object instance like window::resize() ) that can be called in response to particular events occuring in the game loop processing (maybe specifically win32 UI messages). This gives you isolation - the main loop does not need to know about specific object instances, and the object instance doesnt particularly need to know about the game loop.

The instance object can be responsible itself for registering the callback, or else some other class that has general responsibility (and knows about the instance) for setting up the window could do the registering. You probably want to search a bit about event based systems / reactive systems since its a big subject. I dont know if there are standard ways to do this in directx ( I am assuming you probably want to deal with win32 messages / stuff like window resizing) so should stop here and defer to others.

Edit:
Incedently I think dependency injection as a concept relates closely to event systems. here you 'inject' into the handler through the handler's constructor a reference to the instance object (and define in some manner the action to be performed on that object), and then pass off (register) that handler to the main loop achieving desirable decoupling. I am sure someone else will set you straight if this is incorrect.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this