CoCreateInstance in a thread does not work

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
Kilam
Posts: 3
Joined: Mon Jul 21, 2008 6:48 am

CoCreateInstance in a thread does not work

Post by Kilam »

Hi,

I try to get the initialisation of the space navigator device done in a thread. I want to explain why: The device should work with an ActiveX viewer on the web. The viewer starts up in about 1 second when the device is attached but it takes about 7 seconds when the device is detached. As I don't want the user to wait in that case, I have put the initialization code into a thread.
I already found out that I have to call CoInitalize(NULL) in the thread and the thread must live until the main thread ends. Otherwise I would get marshalling errors.

The problem: The program runs now without errors, but it does no longer react on the inputs from the device. Here is the code of the thread:

Code: Select all

void *Thread3DxDevice(void *data)
{
  HRESULT hr;
  CComPtr<IUnknown> _3DxDevice;

  CoInitialize(NULL);
  CCnsweb3dCtrl *ctrl = (CCnsweb3dCtrl *)data;
  ctrl->DebugLog("  Thread 3Dx started.\n");

  // Create the device object
  hr = _3DxDevice.CoCreateInstance(__uuidof(TDxInput::Device));
  if (SUCCEEDED(hr))
  {
    CComPtr<TDxInput> _3DxSimpleDevice;

    hr = _3DxDevice.QueryInterface(&_3DxSimpleDevice);
    if (SUCCEEDED(hr))
    {
        // Associate a configuration with this device
        _3DxSimpleDevice->LoadPreferences(_T("CNSwebViewer"));
        // Connect to the driver
        _3DxSimpleDevice->Connect();

        // Get the interfaces to the sensor and the keyboard;
        ctrl->SetG3DSensor(_3DxSimpleDevice->Sensor);
        ctrl->SetG3DKeyboard(_3DxSimpleDevice->Keyboard);
    }
  }

  while (42)
    Sleep(250);

  ctrl->DebugLog("  Thread 3Dx ended.\n");
  return 0;
}
And this is the code where the results are read in the main thread:

Code: Select all

   if (g3DSensor)
   {
      try {

         CComPtr<TDxInput> pRotation = g3DSensor->Rotation;
         CComPtr<TDxInput>  pTranslation = g3DSensor->Translation;

         // Check if the cap is still displaced
         if (pRotation->Angle > 0. || pTranslation->Length > 0.)
         {
           ...
The ... is where I never get to, as the angle and length is always 0. But if I call the thread function from above directly from the main code (without the sleep), then it works.

I also tried to do the reading of the results in the thread that initializes, but that also does not work (also 0 in rotation and translation).

Thanks for your help.
Kilam
Posts: 3
Joined: Mon Jul 21, 2008 6:48 am

Post by Kilam »

Some additional information I just found out:

The delay only happens, if the driver is installed, but not started. That means, if I just detach the device and then restart my program, it still starts quickly. But when I stop the driver and then restart my program, I get the 7 seconds delay.

I also tested it on a machine with no drivers installed, it starts quickly there too.

=> It only happens when a driver is installed, but not active.
thomasp
Posts: 7
Joined: Wed Jul 23, 2008 2:48 am

Post by thomasp »

And is there a way to programmaticaly check if the driver is running or not before the call to CoCreateInstance ?

Because the 7s delay is a bit annoying
ngomes
Moderator
Moderator
Posts: 3344
Joined: Mon Nov 27, 2006 7:22 am
Contact:

Post by ngomes »

Hi thomasp,
And is there a way to programmaticaly check if the driver is running or not before the call to CoCreateInstance ?
Yes. Refer to this post.
Nuno Gomes
thomasp
Posts: 7
Joined: Wed Jul 23, 2008 2:48 am

Post by thomasp »

Ok i was looking in the tasks list, but your solution seems better ;)

Thank you
Post Reply