2012-12-02 12 views
7

Ich habe versucht, dies seit einiger Zeit zu machen ... Lesen Sie viele Beiträge, aber keiner von ihnen konnte dieses Problem beheben.C# Canon SDK: Kein Rückruf nach CameraCommand_TakePicture

Ich verbinde eine EOS 550D mit dem Canon SDK. Ich bin mit win7 64bit und Visual Studio C# 2010

Was ich Schritt für Schritt zu tun ist:

-> 0 Init SDK

err = EDSDK.EdsInitializeSDK(); 

-> 1 Einführung in Kameraliste

err = EDSDK.EdsGetCameraList(out cameraList); 

-> 2 Erstes Kind zählt

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

-> 3 Wenn ein Kind ist, bekommen erstes Kind

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

-> 4 Öffnen einer Sitzung

err = EDSDK.EdsOpenSession(cameraDev); 

-> 5 das sdk Telling Bilder lokal speichern

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

-> 6 Einstellen der verfügbaren Kapazität auf dem Host-Rechner

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 die Registrierung als staatliche Veranstaltung Handler

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

-> 8 die Registrierung als Objekt Event-Handler

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

....

ich nicht einen Fehler während dies zu tun, Alles scheint in Ordnung zu sein.

Hier sind meine 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; 
    } 

...

Nun mein Problem ist, dass keiner der Handler immer genannt wird. Ich weiß nicht warum, ich searche das Netz fpr einige Zeit versucht, verschiedene Ansätze, aber nicht den Rückruf erhalten ...

Hier ist meine Methode, um die Aufnahme Bild Befehl aufrufen:

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"); 

     } 
    } 

Vielleicht hat jemand hat eine Idee, was ich versuchen könnte, damit das funktioniert?

Vielen Dank im Voraus!

Mit freundlichen Grüßen, Tobias

Antwort

1

Ich bin mit der C++ Version des SDK für einige jetzt Monate.

Nach einem kurzen Scan scheint alles in Ihrem Code in Ordnung.Ich bin mir in diesem Beispiel nicht sicher über die C# -Abfallerfassung/das Scoping, aber Sie möchten sicherstellen, dass Ihre Handler immer noch "herum" sind, nachdem Sie sie festgelegt haben.

Auch für den letzten EdsContext-Parameter verwende ich einen Zeiger auf meine enthaltende Klasse anstelle von Ihrem Nullzeiger.

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

Wenn Sie beißt Sie nicht Ihre Event-Handler in einer Klasse enthalten muß dies möglicherweise kein Problem, aber vielleicht Multi-Threading in Ihrer Anwendung sein. Aus dem EDSDK-Handbuch:

Geben Sie Anwendungsinformationen an, die mit der Callback-Funktion übergeben werden sollen. Alle für Ihre Anwendung benötigten Daten können übergeben werden. In Multithread-Umgebungen wird die Callback-Funktion von einem Thread ausschließlich für das Ereignis ausgeführt. Verwenden Sie es entsprechend, um den this-Zeiger zum Übergeben von Daten an UI-Threads zu bestimmen. Bestimmen Sie einen NULL-Zeiger, wenn er nicht benötigt wird.

Sie können auch versuchen, einen handlePropertyEvent Handler hinzufügen, die auf Änderungen in Weißabgleich/Umschalten auf Live View usw.

6

Ich weiß, dass die SDK-Dokumentation sagt, dass die Callback-Funktionen in einem anderen Thread ausgeführt werden auslösen sollen , aber für mich, SDK 2.11 unter Windows verwenden, geschehen die Rückrufe immer auf dem Hauptthread und scheinen über Windows-Nachrichten gesendet zu werden. Dies bedeutet, dass Sie keine Rückrufe erhalten, wenn Sie keine Nachrichtenpumpe haben. Wenn es sich bei Ihrer App um eine C# -GUI-App handelt, sollten Sie eine Nachricht pumpen, aber wenn es sich um eine Konsolenanwendung handelt, haben Sie wahrscheinlich keine. Versuchen Sie also, Nachrichten manuell zu pumpen, nachdem Sie den Befehl TakePicture gesendet haben. Sie können Application.Run verwenden, aber Sie müssen Application.Exit irgendwo aufrufen, sonst wird Ihre Nachrichtenschleife nie beendet (z. B. können Sie sie nach dem Herunterladen des Bildes von der Kamera aufrufen).

+0

Diese hat für mich gearbeitet; Ich hatte zwei Tage damit zu tun gehabt, da die App hinter einem Webserver von Nancy lief, der selbst als Topshelf-Dienst gehostet wurde, Delegierte in F # geschrieben und Kameraanfragen in einem "MailboxProcessor" anordneten, also gab es eine Million Variablen. Es stellt sich heraus, dass dies das Problem ist. Genauer gesagt musste ich 'InitialzeSDK' und' SetCameraAddedHandler' in einem * neuen * Thread aufrufen und 'Application.Run()' am Ende des Threads aufrufen. –

+0

können Sie bitte ein Codebeispiel bereitstellen? –

+1

Schön, dass ich das herausgefunden habe, Sam! –

0

Ich verbinde eine EOS 550D mit dem Canon SDK. Ich betreibe win7 64bit und Visual Studio C# 2010.

Ihr Problem ist da: das Canon SDK ist für X86 kompiliert. Schau nicht weiter! Sie müssen Ihre Zielarchitektur ändern.

+0

Das ist nicht das Problem. Sicher, das C# -Projekt sollte auf x86 und nicht auf x64 oder Any CPU gesetzt werden, da die native Bibliothek x86 ist, aber es würde eine Vielzahl anderer Probleme geben, wenn diese falsch gesetzt wären. In diesem Fall bin ich mir ziemlich sicher, dass meine Antwort die Antwort ist. – Sam

0

Die Art und Weise, wie Sie das Objektereignis abonnieren, wird von nichts abonniert. Dies ist, wie ich es tun und es funktioniert gut:

event EDSDK.EdsObjectEventHandler SDKObjectEvent; 

void Init(IntPtr cameraDev) 
{ 
    SDKObjectEvent += new EDSDK.EdsObjectEventHandler(objectEventHandler); 
    EDSDK.EdsSetObjectEventHandler(cameraDev, EDSDK.ObjectEvent_All, SDKObjectEvent, IntPtr.Zero); 
} 

Gleiches Prinzip gilt für EdsStateEventHandler, EdsPropertyEventHandler und EdsCameraAddedHandler (und ein wenig anders, aber immer noch mit einem Ereignis EdsProgressCallback)

Mit freundlichen Grüßen

+1

Die Art, wie er den Event-Handler setzt, ist in Ordnung.Er macht das selbe wie Sie, nur dass Sie Ihren Event-Handler durch ein separates (wahrscheinlich unnötiges) Event-Objekt leiten. – Sam