Question

Je me bats avec le Canon EDSDK pendant un certain temps maintenant. Je peux obtenir avec succès la bibliothèque pour enregistrer un fichier directement sur le disque, mais je ne peux pas obtenir une prise de l'octet d'image [] dans la mémoire. Chaque fois que je tente de Marshal.Copy () Stream EDSDK à octet [], je reçois toujours l'erreur suivante:

AccessViolationException: Tentative de lecture ou d'écriture de mémoire protégée. Cela est souvent une indication qu'une autre mémoire est corrompue.

Ci-dessous l'une des variantes de code que j'ai utilisé pour essayer d'obtenir le flux:

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

Les points d'arrêt révèlent (à travers l'objet EdsDirectoryItemInfo) que l'image est bien là, je ne sais pas pourquoi je serais recevais l'exception que je suis. Je suis en train de jouer avec l'idée d'accepter la défaite et juste de lire l'image résultante à partir du disque qu'il écrit si facilement via la méthode createFileStream, mais je dois vraiment être juste capable de manipuler l'image en mémoire.

Toutes les idées?

MISE À JOUR:. Je vois ce comportement dans les deux versions 2.5 et 2.6

Était-ce utile?

La solution

Je viens de googlé pour EdsCreateMemoryStream et a trouvé un échantillon dans lequel il y a un autre appel pour obtenir le pointeur du" flux de mémoire ».

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

Vous pouvez ensuite utiliser pointerToBytes comme source pour lire en Marshal.Copy.

Alors je suppose que ce que vous êtes en train de faire est d'essayer de copier un certain grand nombre d'octets à partir de l'adresse d'une certaine structure de contrôle petite pointée par stream, et donc vous lisez après la fin de cette structure .

Modifier Par ailleurs, vous êtes le code semble que si quelqu'un vous a dit que vous ne devriez avoir une déclaration de retour! C'est vieux conseil concernant les langues comme Fortran et C; il n'a pas de sens dans les langues modernes. Votre code serait plus clair (au moins dans ce cas) si vous immédiatement retourné le code d'erreur chaque fois que vous avez un échec:

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

(Mieux encore, lancer une classe d'exception spécifique contenant le code d'erreur et une chaîne expliquant ce que vous essayez de faire.)

Autres conseils

Je me rends compte que c'est un ancien poste, mais c'est un extrait complet de C # pour le téléchargement à partir d'un flux de mémoire. Il peut être utile pour quelqu'un d'autre. La caméra doit être réglé sur EDSDK.EdsSaveTo.Host ou 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;
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top