Domanda

Here's my issue: I need to pass back two uint32_t's via a single uint32_t (because of how the API is set up...). I can hard code whatever other values I need to reverse the operation, but the parameter passed between functions needs to stay a single uint32_t.

This would be trivial if I could just bit-shift the two 32-bit ints into a single 64-bit int (like what was explained here), but the compiler wouldn't like that. I've also seen mathematical pairing functions, but I'm not sure if that's what I need in this case.

I've thought of setting up a simple cipher: the unint32_t could be the cipher text, and I could just hard code the key. This is an example, but that seems like overkill.

Is this even possible?

È stato utile?

Soluzione 2

Depending on how much trouble this is really worth, you could:

  1. create a global array or vector of std::pair<uint32_t,uint32_t>
  2. pass an index into the function, then your "reverse" function just looks up the result in the array.
  3. write some code to decide which index to use when you have a pair to pass. The index needs to not be in use by anyone else, and since the array is global there may be thread-safety issues. Essentially what you are writing is a simple memory allocator.

As a special case, on a machine with 32 bit data pointers you could allocate the struct and reinterpret_cast the pointer to and from uint32_t. So you don't need any globals.

Beware that you need to know whether or not the function you pass the value into might store the value somewhere to be "decoded" later, in which case you have a more difficult resource-management problem than if the function is certain to have finished using it by the time it returns.

In the easy case, and if the code you're writing doesn't need to be re-entrant at all, then you only need to use one index at a time. That means you don't need an array, just one pair. You could pass 0 to the function regardless of the values, and have the decoder ignore its input and look in the global location.

If both special cases apply (32 bit and no retaining of the value), then you can put the pair on the stack, and use no globals and no dynamic allocation even if your code does need to be re-entrant.

None of this is really recommended, but it could solve the problem you have.

Altri suggerimenti

It is not possible to store more than 32 bits of information using only 32 bits. This is a basic result of information theory.

If you know that you're only using the low-order 16 bits of each value, you could shift one left 16 bits and combine them that way. But there's absolutely no way to get 64 bits worth of information (or even 33 bits) into 32 bits, period.

You can use an intermediate global data structure to store the pair of uint32_t on it, using your only uint32_t parameter as the index on the structure:

struct my_pair {
  uint32_t a, b;
};

std::map<uint32_t, my_pair> global_pair_map;

uint32_t register_new_pair(uint32_t a, uint32_t b) {
  // Add the pair of (a, b) to the map global_pair_map on a new key, and return the
  // new key value.
}

void release_pair(uint32_t key) {
  // Remove the key from the global_pair_map.
}

void callback(uint32_t user_data) {
  my_pair& p = global_pair_map[user_data];

  // Use your pair of uint32_t with p.a, and p.b.
}

void main() {
  uint32_t key = register_new_pair(number1, number2);

  register_callback(callback, key);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top