Passing unknown block of data with it's size?

Started by
29 comments, last by cozzie 7 years, 4 months ago
Hi,
I was wondering if it's possible to be able to pass different sized "blocks" of data to 1 function.
An example:

struct objOne
{
float x, y, z;
};

struct objTwo
{
float a, b, c;
std::string someString;
};

The function:
void ProcessData(sometype pData, const uint pSizeOfObjectInMemory)

And within this function it would like to handle the data (for creating or updating a d3d11 buffer), using the memory size of the object (basically sizeof(...). I want to be able to pass either an object of objOne to the function, or objTwo. Would this be possible by somehow passing a void* to the object's memory or something like that?

Any input is appreciated.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement
Why don't you just create an overload of the function for each possible parameter type?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Yes, it's possible, exactly as you describe. In fact, a lot of standard functions in OS APIs like Windows' or POSIX' do exactly that: they take a pointer to a struct and a size field, using the latter to determine the version of the struct passed in (e.g., an older app might have been compiled when the struct was 8 bytes, but then the struct is extended and apps compiled against newer headers would have a 12 byte size instead).

That said, don't. Use a union if you must, but you don't want that other. Use a std::variant if your compiler is (very) new if you still need a single function. Or use overloading like Apoch recommended, or some polymorphic behavior, etc.

You might be better off asking us about your real problem. This somewhat smells like an XY Problem to me.

Sean Middleditch – Game Systems Engineer – Join my team!

(Seeing this after messing with BSD socks half the day...) <_<

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

Or a template, maybe?


template<typename Type>
void SetConstants(const Type&& data)
{
     static_assert(std::is_trivially_copyable<Type>::value, "Type must be a trivially copyable value."); // we don't want to copy vtables, etc...

     SetConstants((const float*)&data, sizeof(Type));
}

Shouldn't be too bad even if you try to avoid templates for compile time, if you can pack the functions implementation into a generic version.

Thanks guys.

- In my initial attempt I did have overloaded function depending on the 'struct' I'm passing

- the reason why I'm looking for a more flexible way, has to do with the context:

-- it's a ConstantBuffer manager

-- currently I just have 2 possible structs (CB per frame, CB per object), but in the future I expect to have more different struct that need to be passed (updated in the CB)

- I'm looking for a way to pass the data independent of the used struct, to prevent having to add overloaded functions for each new struct I want to use later on

(because the map/unmap etc. functions just needs a block of data, there's no other reason to 'know' which struct it is, other then it's size, for the memory width of the ID3D11Buffer)

@SeanMiddleTech: do you have an example how this would work?

- how do I convert my struct to a void * (in the called function), or do I need another type?)

@Juliean: I've never used templates so far (not avoided them perse, but no need yet to use them). Maybe this is a use-case where they have to come in. But for now I'm leaning towards the "block of data through a void *" or using function overloads (using the same function names, but with different parameter for the to be passed struct).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

But for now I'm leaning towards the "block of data through a void *" or using operator overloads.

If you go for overloading (doesn't have to do with operators though), than thats fine.

If you go for void*, you really should be using a template, if you can. Templates are a much type-safer and hard-to-screw up replacement for pretty much anything you would use void* in C-code (or old-style C++).

Are you actually trying to bind data to callback functions? There are all kinds of idiomatic ways to implement that in C++, ranging from using lambdas in current versions of the language to using std::bind in your grandma's compiler. Consider these in addition to falling back to 1968-era C skills.

Stephen M. Webb
Professional Free Software Developer

OK. So it's either overloading or templates. Any pointers/ hints on how to approach it with templates? (Maybe a good article or even better, example)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Something like this should be a starter:

https://www.justsoftwaresolutions.co.uk/articles/intrototemplates.pdf

With that in mind, look at the example I gave you. Template boils down to having a function with different possible input-vales, so instead of void* you have T*, where T resolves to what you actually put into the function at this point. You should've already worked with classes that use this concept, like vector<> or similiar, right? So this should be a good starting point for writing template code yourself, which is something that really comes in handy at some point or another anyways :)

This topic is closed to new replies.

Advertisement