2009-07-05 13 views
2

私はしばらくの間、キヤノンEDSDKと戦ってきました。私は正常にディスクに直接ファイルを保存するライブラリを取得することができますが、私は画像のバイト[]をメモリに保持することはできません。私がMarshal.Copy()にEDSDKストリームをバイト[]にしようとすると、私はいつも次のエラーを受け取ります:キヤノンEDSDKメモリストリーム画像

保護されたメモリを読み書きしようとしました。これはしばしば、他のメモリが壊れていることを示します。以下は

私はストリームを試してみて、取得するために使用したコードのバリエーションの一つである:

 private uint downloadImage(IntPtr directoryItem) 
     { 
      uint err = EDSDK.EDS_ERR_OK; 
      IntPtr stream = IntPtr.Zero; 

      // Get information of the directory item. 
      EDSDK.EdsDirectoryItemInfo dirItemInfo; 
      err = EDSDK.EdsGetDirectoryItemInfo(directoryItem, out dirItemInfo); 

      // Create a file stream for receiving image. 
      if (err == EDSDK.EDS_ERR_OK) 
      { 
       err = EDSDK.EdsCreateMemoryStream(dirItemInfo.Size, out stream); 
      } 

      // Fill the stream with the resulting image 
      if (err == EDSDK.EDS_ERR_OK) 
      { 
       err = EDSDK.EdsDownload(directoryItem, dirItemInfo.Size, stream); 
      } 

      // Copy the stream to a byte[] and 
      if (err == EDSDK.EDS_ERR_OK) 
      { 
       byte[] buffer = new byte[dirItemInfo.Size]; 

       GCHandle gcHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned); 
       // The following line is where it blows up... 
       Marshal.Copy(stream, buffer, 0, (int)dirItemInfo.Size); 

       // ... Image manipulation, show user, whatever 
      } 

      return err; 
     } 

ブレークポイントは、私はちょうどドン、画像が実際にあること(EdsDirectoryItemInfoオブジェクトを介して)明らかになぜ私が例外であるのか分かりません。私は敗北を受け入れるというアイディアを借りて、ディスクから結果のイメージを読み込み、CreateFileStreamメソッドを使って簡単に書き込みますが、実際にはメモリ内のイメージを操作できるだけです。

アイデア?

更新:この現象は、バージョン2.5と2.6の両方で発生します。

+0

?私はそれまでにさえ得られない。具体的には、オブジェクトイベントハンドラ関数を呼び出すことができません。 – andrewrk

答えて

4

私はちょうどEdsCreateMemoryStreamfound a sampleのためのグーグルでは、 "メモリストリーム"からポインタを取得する別の呼び出しがあります。

IntPtr pointerToBytes; 
EDSDKLib.EDSDK.EdsGetPointer(stream, out pointerToBytes); 

その後、Marshal.Copy内からの読み取りをソースとしてpointerToBytesを使用することができます。

私はあなたが現在行っていることは、streamが指し示す小さなコントロール構造のアドレスから始まるいくつかの大きなバイト数をコピーしようとしていると推測します。構造。

編集:ところで、コードは、誰かが返信文を1つだけ持っていると言ったかのように見えます。それはFortranやCのような言語に関する古いアドバイスです。現代の言語では意味をなさない。エラーコードと説明する文字列を含む特定の例外クラスをスローし、まだ

if ((err = EDSDK.EdsBlahBlah(...)) != EDSDK.EDS_ERR_OK) 
    return err; 

(ベター:あなたはすぐにエラーコードあなたが失敗しましたびに返された場合、あなたのコードは、(少なくとも、このケースでは)明確になります)あなたは何をしようとしていたのですか?)

+0

この特定のメソッドは、EDSDKのラッパーメソッド(それをテストしたもの)に過ぎません。私は家に帰るときにポインタを試してみるよ。 –

3

これは古い投稿ですが、これはメモリストリームからダウンロードするための完全なC#スニペットです。それは他の人にとって有益かもしれません。カメラはEDSDK.EdsSaveTo.HostまたはEDSDK.EdsSaveTo.Both

に設定する必要があなたのコード(どこかに)あなただけのディスクにかかった画像をダウンロードするには掲載いただけません
 uint error = EDSDK.EDS_ERR_OK; 
     IntPtr stream = IntPtr.Zero; 

     EDSDK.EdsDirectoryItemInfo directoryItemInfo; 

     error = EDSDK.EdsGetDirectoryItemInfo(this.DirectoryItem, out directoryItemInfo); 

     //create a file stream to accept the image 
     if (error == EDSDK.EDS_ERR_OK) 
     { 
      error = EDSDK.EdsCreateMemoryStream(directoryItemInfo.Size, out stream); 
     } 


     //down load image 
     if (error == EDSDK.EDS_ERR_OK) 
     { 
      error = EDSDK.EdsDownload(this.DirectoryItem, directoryItemInfo.Size, stream); 
     } 

     //complete download 
     if (error == EDSDK.EDS_ERR_OK) 
     { 
      error = EDSDK.EdsDownloadComplete(this.DirectoryItem); 
     } 


     //convert to memory stream 
     IntPtr pointer; //pointer to image stream 
     EDSDK.EdsGetPointer(stream, out pointer); 

     uint length = 0; 
     EDSDK.EdsGetLength(stream, out length); 

     byte[] bytes = new byte[length]; 

     //Move from unmanaged to managed code. 
     Marshal.Copy(pointer, bytes, 0, bytes.Length); 

     System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(bytes); 
     Image image = System.Drawing.Image.FromStream(memoryStream); 

     if (pointer != IntPtr.Zero) 
     { 
      EDSDK.EdsRelease(pointer); 
      pointer = IntPtr.Zero; 
     } 


     if (this.DirectoryItem != IntPtr.Zero) 
     { 
      EDSDK.EdsRelease(this.DirectoryItem); 
      this.DirectoryItem = IntPtr.Zero; 
     } 

     if (stream != IntPtr.Zero) 
     { 
      EDSDK.EdsRelease(stream); 
      stream = IntPtr.Zero; 
     } 
関連する問題