C# 调用函数时出错,[调用堆栈中的PInvoke函数]

C# 调用函数时出错,[调用堆栈中的PInvoke函数],c#,.net,pointers,C#,.net,Pointers,我有以下代码,一旦我运行我的应用程序,我得到这个错误 有人知道我如何修复这个错误吗 错误: 调用PInvoke函数“testcamera!”!EDSDKLib.EDSDK::EdsDownloadEvfImage'使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配 IntPtr cameraDev; bool LVrunning = false; uint err

我有以下代码,一旦我运行我的应用程序,我得到这个错误

有人知道我如何修复这个错误吗

错误:

调用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);
            }

在执行平台调用(p/invoke)时,您必须告诉CLR参数是什么(这决定了它们如何被封送),以及目标本机方法的调用约定是什么,以便运行时知道如何生成代码以正确地推送参数并在调用后清理堆栈。如果签名不匹配,则会出现与您看到的类似的运行时错误

错误消息很好地解释了问题:

这可能是因为托管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);
            }
EDSDK.EdsCreateEvfImageRef
的p/Invoke签名与实现此功能的实际本机方法签名进行比较


通过在
DllImport
属性上指定属性,可以更改p/Invoke的调用约定。更有可能的是,
EDSDK.EdsCreateEvfImageRef
的调用约定应该与其他P/Invokes的调用约定相匹配。

请对该函数使用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);   

我遇到了与海报相同的问题,结果我需要将使用EDSDK库(v2.10)的项目更改为使用.NET 3.5而不是.NET 4.0。

请提供更多信息-dllimport,EdsDownloadEvfImage签名这是我的dllimport,[dllimport(“EDSDK.dll”)]公共外部静态uint EdsCreatevFimageRef(IntPtr inStreamRef,out IntPtr outeffimageref);什么是函数本机签名?我将我的dll导入,[DllImport(“EDSDK.dll”)]公共外部静态uint EdsCreateEvfImageRef(IntPtr inStreamRef,out IntPtr outeffimageref);我的代码哪里错了?你的其他P/调用看起来像什么?EdsDownloadEvfImage的本机签名看起来像什么?我不确定在哪里可以找到这个本机代码签名,我没有dll的源代码。我只得到了dllitself@user1400:在这种情况下,您需要一些文档来告诉您。如果此DLL作为某些SDK的一部分,我希望它会附带一个.h文件或其他一些内容的代码描述。如果DLL不是来自某些SDK,那么您确定调用它导出的任何函数是可能的(并且是合法的)吗?它是SDK的一部分(canon camera的EDSDK 2.8)它有一些头文件
Cdecl
:调用者清理堆栈。这允许使用varargs调用函数,这使得它适合用于接受可变数量参数的方法。它使每个函数调用包含堆栈清理代码。我也有类似的问题,并通过将.net版本改为3.5