функция вызова ошибки, [вызов функции PInvoke разбалансирует стек] - PullRequest
6 голосов
/ 20 сентября 2010

у меня следующий код, после запуска приложения я получаю эту ошибку

кто-нибудь знает, как я могу исправить эту ошибку?

ОШИБКА:

вызов функции PInvoke'testcamera! EDSDKLib.EDSDK :: EdsDownloadEvfImage' разбалансировал стек.Это вероятно потому, что управляемая подпись PInvoke не совпадает с неуправляемой целевой подписью.Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи

 IntPtr cameraDev;
            bool LVrunning = false;
            uint err = EDSDK.EDS_ERR_OK;
            uint device = 0;
            IntPtr MemStreamRef = new IntPtr(0);

            IntPtr EvfImageRef = new IntPtr(0);
            PictureBox pbLV;

            public LiveView(IntPtr c, PictureBox p)
            {
                cameraDev = c;
                pbLV = p;
            }

            internal void StartLiveView()
            {
                //LVrunning = true;
                //int i = 0;

                // Get the output device for the live view image
                err = EDSDK.EdsGetPropertyData(cameraDev, EDSDK.PropID_Evf_OutputDevice, 0, out device);
                Debug.WriteLineIf(err != EDSDK.EDS_ERR_OK, String.Format("Get Property Data failed: {0:X}", err));
                Debug.WriteLineIf(err == EDSDK.EDS_ERR_OK, String.Format("Liveview output is: {0:x}", device));

                Thread.Sleep(1000);

                // Set the computer as live view destination
                if (err == EDSDK.EDS_ERR_OK)
                {
                    err = EDSDK.EdsSetPropertyData(cameraDev, EDSDK.PropID_Evf_OutputDevice, 0,
                        Marshal.SizeOf(EDSDK.EvfOutputDevice_PC), EDSDK.EvfOutputDevice_PC);
                    Debug.WriteLine(String.Format("Liveview output to computer: {0:X}", err));
                }

                // Create a memory stream for the picture
                if (err == EDSDK.EDS_ERR_OK)
                {
                    err = EDSDK.EdsCreateMemoryStream(0, out MemStreamRef);
                    Debug.WriteLine(String.Format("Create Memory Stream: {0:X}", err));
                }

                // Get a reference to a EvfImage

                if (err == EDSDK.EDS_ERR_OK)
                {

**//i get error here**
                     **err = EDSDK.EdsCreateEvfImageRef(MemStreamRef, out EvfImageRef);** 

                    Debug.WriteLine(String.Format("Create Evf Imaage Ref: {0:X}", err));
                }

                Thread.Sleep(2000);
            }

Ответы [ 3 ]

24 голосов
/ 31 октября 2010

Пожалуйста, используйте соглашение о вызовах Cdecl для этой функции.Не спрашивайте меня, почему, это просто работает.

[DllImport("EDSDK.dll", CallingConvention=CallingConvention.Cdecl)]
public extern static uint EdsCreateEvfImageRef(IntPtr inStreamRef, out IntPtr outEvfImageRef);

[DllImport("EDSDK.dll",CallingConvention=CallingConvention.Cdecl)]
public extern static uint EdsDownloadEvfImage(IntPtr inCameraRef, IntPtr outEvfImageRef);   
3 голосов
/ 20 сентября 2010

При выполнении вызова платформы (P / Invoke) вы должны сообщить CLR, каковы параметры (которые определяют, как они распределяются), а также каково соглашение о вызовах целевого нативного метода, чтобы среда выполнения знала как сгенерировать код, чтобы правильно выдвинуть аргументы и очистить стек после вызова. Если подписи не совпадают, вы получите ошибки времени выполнения, аналогичные тем, которые вы видите.

Сообщение об ошибке хорошо объясняет проблему:

Вероятно, это связано с тем, что управляемая подпись PInvoke не совпадает с неуправляемой целевой подписью. Убедитесь, что соглашение о вызовах и параметры подписи PInvoke соответствуют целевой неуправляемой подписи

Сравните сигнатуру P / Invoke для EDSDK.EdsCreateEvfImageRef с фактической сигнатурой собственного метода, который реализует это.

Вы можете изменить соглашение о вызовах P / Invoke, указав свойство CallingConvention в атрибуте DllImport. Скорее всего, соглашение о вызовах для EDSDK.EdsCreateEvfImageRef должно совпадать с соглашением о вызовах других ваших P / Invokes.

2 голосов
/ 13 июня 2011

У меня была та же проблема, что и у автора, оказалось, что мне нужно было изменить свой проект с использованием библиотеки EDSDK (v2.10), чтобы использовать .NET 3.5 вместо .NET 4.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...