2012-12-02 9 views
7

私はしばらくこの作品を作ろうとしています...多くの投稿を読んでいますが、どれもこの問題を解決することはできません。c#Canon SDK:CameraCommand_TakePictureの後のコールバックがありません

Canon SDKを使用してEOS 550Dに接続しています。 - > 0初期SDK

err = EDSDK.EdsInitializeSDK(); 

- > 1カメラリストに

を取得

:私は、私は段階的に行うことであるwin7の64ビット版およびVisual StudioのC#の2010

を実行しています

err = EDSDK.EdsGetCameraList(out cameraList); 

- > 2子カウントの取得

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

- > 3子がある場合は、

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

最初の子を取得する - ローカル

画像を保存するためのSDKを伝える> 5 - セッション

err = EDSDK.EdsOpenSession(cameraDev); 

を開く> 4は、

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

- > 6ホストマシン上で使用可能な容量を設定

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状態イベントハンドラ

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

- > 8 Registringオブジェクトのイベントハンドラ

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

....

私はこれをやっている間にエラーを取得いけません、すべてがうまくいくようです。ここで

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; 
    } 

...

私のハンドラですだから今私の問題は、ハンドラのいずれも、これまでと呼ばれていないことです。異なるアプローチを試みたが、コールバックを取得していない、私はかなりの時間FPRネットをsearche、理由がわからない...ここで

はテイク絵コマンドを呼び出す私の方法であって、

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

     } 
    } 

たぶん誰か私はこの仕事をしようとすることができるアイデアを持っていますか?

ありがとうございます!

敬具、 トビアス

答えて

1

私は今、数ヶ月のためのSDKのC++バージョンを使用しています。

クイックスキャンの後、すべてのコードで問題なく表示されます。私はこの例ではC#ガベージコレクション/スコープについてはわかりませんが、ハンドラが設定された後もハンドラが "周り"になっていることを確認したいと思っています。

また、最後のEdsContextパラメータでは、ゼロポインタの代わりに私のクラスを含むポインタを使用します。

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

あなたはこれが問題ではないかもしれませんクラスであなたのイベントハンドラを含める必要はありませんが、おそらくあなたのアプリでマルチスレッドはあなたを刺された場合。 EDSDKマニュアルから:

コールバック関数によって渡されるアプリケーション情報を指定します。アプリケーションに必要なデータはすべて渡すことができます。 マルチスレッド環境では、コールバック関数は、イベント専用のスレッドによって実行されます。このポインタを指定してUIスレッドにデータを渡すように、適切に使用してください。必要でない場合はNULLポインタを指定してください。

あなたはまた、試してみて、SDKのドキュメントは、コールバック関数は、別のスレッドで実行されることを述べている私が知っているライブビューに切り替える/ホワイトバランスの変化でトリガする必要がありhandlePropertyEventハンドラなど

6

を追加することができます私の場合、WindowsではSDK 2.11を使用しているので、コールバックは常にメインスレッドで発生し、Windowsのメッセージを介して送信されるようです。つまり、メッセージポンプがない場合は、コールバックを取得しません。あなたのアプリがC#のGUIアプリの場合はメッセージポンプが必要ですが、コンソールアプリケーションの場合はおそらくそれがないので、TakePictureコマンドを送信した後に手動でポンピングを試みてください。 Application.Runを使用することができますが、Application.Exitをどこかに呼び出す必要があります。そうしないと、メッセージループは終了しません(たとえば、カメラから画像をダウンロードした後に呼び出すことができます)。

+0

これについて私のために働いた;私は、アプリケーションがトップシェルフサービスとして自己ホストされたナンシーウェブサーバーの背後にあるので、2日間それを閉じていました、F#で書かれたデリゲートと 'MailboxProcessor'でカメラ要求をキューイングするので、これは固定されていることが分かります。具体的には、* new *スレッドで 'InitialzeSDK'と' SetCameraAddedHandler'を呼び出し、スレッドの最後に 'Application.Run()'を呼び出す必要がありました。 –

+0

いくつかのコード例を教えてください。 –

+1

それはサムを考え出していい人! –

0

Canon SDKを使用してEOS 550Dに接続しています。私はwin7 64bitとVisual Studio c#2010を実行しています。

問題があります:キヤノンSDKはX86用にコンパイルされています。さらに見ないでください!ターゲットアーキテクチャを変更する必要があります。

+0

これは問題ではありません。確かに、ネイティブライブラリがx86であるため、C#プロジェクトはx64やAny CPUではなくx86に設定する必要がありますが、それが正しく設定されていないと他にも多数の問題があります。この場合、私は私の答えが答えだと合理的に確信しています。 – Sam

0

オブジェクトイベントを購読する方法は、実際には何も購読していません。 これは私がそれを行う方法であり、それは正常に動作します:

event EDSDK.EdsObjectEventHandler SDKObjectEvent; 

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

同じ原理が(イベントEdsProgressCallbackで、まだ、ビット異なるが)EdsStateEventHandler、EdsPropertyEventHandlerとEdsCameraAddedHandlerのために行く

種類は

+1

彼がイベントハンドラを設定する方法は問題ありません。彼はあなたと同じことをしていますが、イベントハンドラを別の(恐らく不要な)イベントオブジェクトにルーティングしている点を除いて、実際には同じことをしています。 – Sam

関連する問題