Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Canon SDK: No callback after CameraCommand_TakePicture

Tags:

c#

canon-sdk

i've been trying to make this work for some time now... read a lot of posts but none of them could fix this issue.

I am connecting to a EOS 550D using the Canon SDK. I am running win7 64bit and Visual Studio c# 2010.

What I do step by step is:

--> 0 Init SDK

 err = EDSDK.EdsInitializeSDK();

--> 1 Getting camera list

 err = EDSDK.EdsGetCameraList(out cameraList);

--> 2 Getting child count

 err = EDSDK.EdsGetChildCount(cameraList, out cameraCount);

--> 3 If there is a child, get first child

  err = EDSDK.EdsGetChildAtIndex(cameraList, 0, out cameraDev);

--> 4 Opening a session

err = EDSDK.EdsOpenSession(cameraDev);

--> 5 Telling the sdk to save images locally

IntPtr saveTo = (IntPtr)EDSDK.EdsSaveTo.Host;
err = EDSDK.EdsSetPropertyData(cameraDev, EDSDK.PropID_SaveTo, 0, 4, saveTo);

--> 6 Setting the available capacity on the host machine

 EDSDK.EdsCapacity capacity = new EDSDK.EdsCapacity();

 if (err == EDSDK.EDS_ERR_OK)
 {
     capacity.NumberOfFreeClusters = 0x7FFFFFFF;
     capacity.BytesPerSector = 0x1000;
     capacity.Reset = 1;
     err = EDSDK.EdsSetCapacity(cameraDev, capacity);
 }

--> 7 Registring State event Handler

err = EDSDK.EdsSetCameraStateEventHandler(cameraDev, EDSDK.StateEvent_All, stateEventHandler,   new IntPtr(0));

--> 8 Registring Object Event Handler

 EDSDK.EdsObjectEventHandler edsObjectEventHandler = new EDSDK.EdsObjectEventHandler(objectEventHandler);
               err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);

....

I dont get any error while doing this, all seems to be fine.

Here are my Handler

 private uint objectEventHandler(uint inEvent, IntPtr inRef, IntPtr inContext)
    {
        Console.WriteLine("HALLLOOOOOOOOOO");
        switch (inEvent)
        {
            case EDSDK.ObjectEvent_DirItemCreated:
                //this.invokeNewItemCreatedEvent(new NewItemCreatedEventArgs(getCapturedItem(inRef)));
                Console.WriteLine("Directory Item Created");
                break;
            case EDSDK.ObjectEvent_DirItemRequestTransfer:
                Console.WriteLine("Directory Item Requested Transfer");
                break;
            default:
                Console.WriteLine(String.Format("ObjectEventHandler: event {0}, ref {1}", inEvent.ToString("X"), inRef.ToString()));
                break;
        }

        return 0x0;
    }








    public uint stateEventHandler(uint inEvent, uint inParameter, IntPtr inContext)
    {
        Console.WriteLine("stateEventHandler " + inEvent);
        switch (inEvent)
        {
            case EDSDK.StateEvent_JobStatusChanged:
                Console.WriteLine(String.Format("There are objects waiting to be transferred.  Job status {0}", inParameter));
                break;

            case EDSDK.StateEvent_ShutDownTimerUpdate:
                if (inParameter != 0)
                    Console.WriteLine(String.Format("shutdown timer update: {0}", inParameter));
                break;

            case EDSDK.ObjectEvent_DirItemRequestTransfer:
                //WHAT I NEED!!!
                Console.WriteLine("Hallo DirItemRequestTransfer");
                //DownloadImage(obj);
                break;


            default:
                Console.WriteLine(String.Format("StateEventHandler: event {0}, parameter {1}", inEvent, inParameter));
                break;
        }
        return 0;
    }

...

So now my problem is that none of the handler is ever called. Don't know why, I searche the net fpr quite some time, tried different approaches but did not get the callback...

Here is my method calling the take picture command:

 public void takePic()
    {
        if (cameraOpened)
        {
           Console.WriteLine( "taking a shot");

            err = EDSDK.EdsSendCommand(cameraDev, EDSDK.CameraCommand_TakePicture, 0);
            if (err != EDSDK.EDS_ERR_OK)
                Console.WriteLine("TakeCommand Error: " + err.ToString());

            Console.WriteLine("Finished taking a shot");

        }
    }

Maybe someone has an idea what I could try to make this work?

Thanks in advance!

Best regards, Tobias

like image 843
Tobi123 Avatar asked Dec 02 '12 12:12

Tobi123


2 Answers

I know the SDK documentation says that the callback functions will be executed in another thread, but for me, using SDK 2.11 under Windows, the callbacks always happen on the main thread and seem to be sent via Windows messages. This means that if you don't have a message pump you won't get the callbacks. If your app is a C# GUI app you should have a message pump, but if it's a console app you probably won't have one, so try manually pumping messages after sending the TakePicture command. You can use Application.Run but you'll need to call Application.Exit somewhere or else your message loop will never exit (e.g. you can call it after downloading the picture from the camera).

like image 122
Sam Avatar answered Nov 13 '22 10:11

Sam


I'm using the C++ version of the SDK for some months now.

After a quick scan, all seems fine in your code. I'm not sure about the C# garbage collection/scoping in this example, but you want to make sure your handlers still "around" after you've set them.

Also, for the final EdsContext parameter I use a pointer to my containing class instead of your zero pointer.

err = EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, edsObjectEventHandler, IntPtr.Zero);

If you don't need to contain your event handlers in a class this might not be a problem, but perhaps multi-threading in your app bites you. From the EDSDK manual:

Designate application information to be passed by means of the callback function. Any data needed for your application can be passed. In multithreaded environments, the callback function is executed by a thread exclusively for the event. Use it appropriately, as in designating the this pointer to pass data to UI threads. Designate a NULL pointer if it is not needed.

You could also try and add a handlePropertyEvent handler that should trigger on changes in white balance/ switching to liveview, etc.

like image 39
gdh Avatar answered Nov 13 '22 09:11

gdh