Frage

Ich habe jetzt eine Zeit lang mit der Canon EDSDK kämpfen. Ich kann erfolgreich die Bibliothek bekommen, um direkt auf der Festplatte eine Datei zu speichern, aber ich kann nicht halten, das Bild, byte [] im Speicher erhalten. Immer, wenn ich zu Marshal.Copy () dem EDSDK Strom versuchen, byte [], ich folgende Fehlermeldung immer erhalten:

Access: Versuchte zu geschützten Speicher zu lesen oder zu schreiben. Dies ist häufig ein Hinweis darauf, dass andere Speicher beschädigt ist.

Im Folgenden finden Sie eine der Änderungen des Codes, die ich verwendet habe, um zu versuchen, den Strom zu bekommen:

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

Haltepunkte zeigen (Durch das EdsDirectoryItemInfo Objekt), dass das Bild in der Tat gibt es, ich weiß nur nicht, warum ich die Ausnahme würde bekommen, was ich bin. Ich habe mit dem Gedanken Niederlage akzeptieren und habe gerade gelesen das sich ergebende Bild von der Festplatte, die es so leicht über die CreateFileStream Methode schreibt, aber ich sollte eigentlich nur in der Lage sein, das Bild im Speicher zu manipulieren.

Irgendwelche Ideen?

UPDATE:. Ich sehe dieses Verhalten in beiden Versionen 2.5 und 2.6

War es hilfreich?

Lösung

Ich googeln nur für EdsCreateMemoryStream und fand eine Probe , in dem es einen weiteren Anruf ist, um den Zeiger von dem bekommen" Speicher-Stream “.

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

Sie können dann als Quelle verwenden pointerToBytes von in Marshal.Copy zu lesen.

Also würde ich denke, dass das, was Sie gerade tun versucht, eine große Anzahl von Bytes von der Adresse von einiger kleinen Kontrollstruktur von stream darauf beginnen zu kopieren, und daher sind Sie über das Ende dieser Struktur lesen .

Edit: By the way, sind Sie Code sieht aus, als wenn jemand Ihnen gesagt, dass Sie nur eine return-Anweisung haben sollte! Das ist alten Rat zu Sprachen wie Fortran und C beziehen; es macht keinen Sinn in der modernen Sprachen machen. Code wäre klarer (zumindest in diesem Fall), wenn Sie sofort den Fehlercode jedes Mal zurück Sie einen Fehler bekommen:

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

(Noch besser wäre es, werfen eine bestimmte Ausnahmeklasse mit dem Fehlercode und eine Zeichenfolge zu erklären, was Sie tun wollten.)

Andere Tipps

Ich weiß, dass dies eine alte Post, aber das ist ein kompletter C # Code-Schnipsel, um aus einem Speicher-Stream herunterzuladen. Es kann für jemand anderen nützlich sein. Die Kamera muss EDSDK.EdsSaveTo.Host oder EDSDK.EdsSaveTo.Both zu setzen

        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;
        }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top