Hi,
Once you retain a channel from the manager - this is now your channel. The manager releases it's own reference to the channel right after the attach or detach event returns. Also, keep in mind that attach and detach events from the manager for the same channel are not going to give you the same handle - these channels are created as needed for attach/detach events - so if you want to keep a list of attached channels, you can't just compare pointers when a detach event comes in.
Once you retain a channel, you can open/close/open, etc. however many times you like. Once you call Phidget_release() or Phidget_delete(), the channel is freed and you can't use it any longer.
I'm able to retain a channel from a manger attach event and open / close / open / close / etc. as many times as I like. When you say "If another channel is selected, I close the channel, but then it's made inaccessible by the manager (I cannot release it, and I cannot re-open it, if it's later selected again)." - I'm not sure what this means, can you elaborate.
Some simple example code:
Code: Select all
#include "stdlib.h"
#include "stdio.h"
#include "Windows.h"
//#include "unistd.h"
#include "phidget22.h"
PhidgetManagerHandle man;
int cnt;
#define PRINT_RES(func) do { \
char error[4096]; \
size_t errLen = sizeof(error); \
const char *errorDesc; \
PhidgetReturnCode res; \
if ((func) != EPHIDGET_OK) { \
Phidget_getLastError(&res, &errorDesc, error, &errLen); \
printf("================================================================\n"); \
printf("FAIL: " #func "\n%s (0x%02x)\n%s\n", errorDesc, res, error); \
printf("================================================================\n"); \
} else { \
printf("SUCCESS: " #func "\n"); \
} \
} while (0)
#define MAXCHANNELS 2000
PhidgetHandle managerChannels[MAXCHANNELS] = { 0 };
void CCONV attach(PhidgetManagerHandle phid, void *ctx, PhidgetHandle Channel) {
const char *name;
PRINT_RES(Phidget_getChannelName(Channel, &name));
printf("Attach: %s (%d)\n", name, cnt);
PRINT_RES(Phidget_retain(Channel));
managerChannels[cnt] = Channel;
cnt++;
}
int main() {
PhidgetDigitalOutputHandle d = NULL;
PhidgetReturnCode res1;
int i;
PRINT_RES(PhidgetLog_enable(PHIDGET_LOG_DEBUG, "test.log"));
PRINT_RES(PhidgetManager_create(&man));
PRINT_RES(PhidgetManager_setOnAttachHandler(man, attach, NULL));
PRINT_RES(PhidgetManager_open(man));
// Wait for the manager to pick up channels
Sleep(5000);
// Look for a paricular channel in the retained channels
i = 0;
while (managerChannels[i]) {
PhidgetHandle ch = managerChannels[i++];
int32_t deviceSerialNumber;
int channel;
Phidget_ChannelClass channelClass;
PRINT_RES(Phidget_getDeviceSerialNumber(ch, &deviceSerialNumber));
PRINT_RES(Phidget_getChannel(ch, &channel));
PRINT_RES(Phidget_getChannelClass(ch, &channelClass));
if (deviceSerialNumber == 611346 && channel == 0 && channelClass == PHIDCHCLASS_DIGITALOUTPUT) {
d = (PhidgetDigitalOutputHandle)ch;
break;
}
}
if (d != NULL) {
printf("Found interesting channel\n");
while (1) {
PRINT_RES(res1 = Phidget_openWaitForAttachment((PhidgetHandle)d, 5000));
if (res1 == EPHIDGET_OK) {
PRINT_RES(PhidgetDigitalOutput_setState(d, 1));
Sleep(1000);
PRINT_RES(Phidget_close((PhidgetHandle)d));
}
Sleep(1000);
}
}
PRINT_RES(PhidgetManager_delete(&man));
return 0;
}
The PRINT_RES macro is just there as a convenience, you could remove that.
-Patrick