views:

82

answers:

3

Hi,

I have a dll which requires me to set a callback function for it (actually it's a camera sdk and it will callback my function when it receives a picture). I wanna have multiple (user input) cameras but I can't. Since I should make unknown number of callback functions.

the easy way is to make a class (camera) which have a function for its callback. but I cannot pass the pointer of member of the class to the dll (it only accept (void)(image*))

any possible solution?

+1  A: 

Try creating a global list of all the function objects to be called, then add a single function that calls each of the callbacks with the required data. Something like this:

std::vector<ICallback*> g_callbacks;

void callback_wrapper( image * image )
{
  for(unsigned int i=0; i<g_callbacks.size(); ++i)
  {
     g_callbacks[i]->process( image );
  }
}

Then you set the callback used by the SDK to the callback_wrapper function.

Michael Anderson
thank you for your reply, this is not gonna work for me.this way all cameras will receive all the images from all the cameras!I need each camera to get only it's own images.
MBZ
A: 

Does camera SDK support multiple cameras connection? If not, you need to talk with SDK provider.

If SDK supports multiple connection, it must provide the way to recognize the camera in callback function. But actual answer is in SDK itself. What is the "image" type, maybe it contains camera ID? Maybe camera ID is supplied when a client code makes callback subscription? Something like this:

void Callback0(image*);
void Callback1(image*);

SubscribeImageCallback(0, Callback0);  // camera 0
SubscribeImageCallback(1, Callback1);  // camera 1

Actual answer to your question depends on the camera SDK interface.

Alex Farber
thank you so much for your answer.the only possible way to recognize the the camera ID is from the memory address of the image. but it gonna solve the problem :)
MBZ
A: 

Depending on the OS, you may be able to create dynamic functions for each callback object. I've done exactly that for callbacks from legacy code which didn't have any facility to pass a value to the callback.

Create a small prototype forwarding function with the type the library expects which then calls the real callback function with an easily seen extra parameter

void Call01020304 () {
    CallWithValue(0x01020304);
}

Compile it and look at the hex for the assembly. It should be obvious where the constant is.

You then use VirtualAlloc + PAGE_EXECUTE_READWRITE or mmap + PROT_EXEC to allocate some memory which can be executed. Allocation is usually in 4K blocks, so create a class to manage the functions, as you will be allocating enough for many in one go.

When you need a new callback function with a unique value, copy the bytes of the prototype with appropriately changed value into your executable memory, and return the pointer to it as the callback function.

Pete Kirkham