C++ WIA运行时检查失败#0 C++;(Windows图像采集)

C++ WIA运行时检查失败#0 C++;(Windows图像采集),c++,runtime-error,wia,C++,Runtime Error,Wia,我尝试使用WIA向摄像机发送数据。 我需要在C++中开发这个,所以我使用官方的“教程” 我知道另一个与C语言合作的项目,我想在C++上做同样的工作。 (C#项目日期:) 当我想使用Escape方法时,我得到 Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declare

我尝试使用WIA向摄像机发送数据。 我需要在C++中开发这个,所以我使用官方的“教程” 我知道另一个与C语言合作的项目,我想在C++上做同样的工作。 (C#项目日期:)

当我想使用
Escape
方法时,我得到

Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.
This is usually a result of calling a function declared with one calling
convention with a function pointer declared with a different calling convention.
错误,我希望你能帮助我解决这个问题。 我的代码如下所示:

 //initialize wia
HRESULT h = CoInitialize(NULL);
IWiaDevMgr* pWiaDevMgr = NULL;
//create wia device manager
HRESULT hr = CreateWiaDeviceManager(&pWiaDevMgr);
//show connected devices and get deviceId
BSTR bstrDeviceID = SysAllocString(L"");
HRESULT hr2 = EnumerateWiaDevices(pWiaDevMgr, &bstrDeviceID);
//create device with device id
IWiaItem* ppWiaDevice;
HRESULT hr3 = CreateWiaDevice(pWiaDevMgr, bstrDeviceID, &ppWiaDevice);

//case IWiaItem to IWiaItemExtras
IWiaItemExtras* ppWiaExtra = (IWiaItemExtras*)ppWiaDevice;

//try to send data
DWORD dwEscapeCode = 256;
BYTE* lpInData = new unsigned char[37]{ 0x01, 0x92, 0x00 , 0x00 , 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x01 ,
    0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
    0x00, 0x00, 0x00, 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x03 ,
    0x00 ,   0x00 , 0x00 , 0x03 , 0x00 , 0x00 , 0x00 }; 
DWORD cbInDataSize = sizeof(lpInData);

BYTE* pOutData = new unsigned char[4]{ 0x00 , 0x00,0x00, 0x00};
DWORD dwOutDataSize = sizeof(pOutData);

DWORD pdwActualDataSize = NULL;

BSTR bstre = SysAllocString(L"");
//just to test if ppWiaExtra is working
HRESULT hr6 = ppWiaExtra->GetExtendedErrorInfo(&bstre); //works
//try to send data with Escape Method
//see https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-iwiaitemextras-escape
HRESULT hr5 = ppWiaExtra->Escape(dwEscapeCode, lpInData, cbInDataSize, pOutData, dwOutDataSize, &pdwActualDataSize); //Run-Time Check Failure #0
我使用的方法与上的示例代码中的方法相同

逃逸方法是:

virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Escape( 
        /* [in] */ DWORD dwEscapeCode,
        /* [size_is][in] */ __RPC__in_ecount_full(cbInDataSize) BYTE *lpInData,
        /* [in] */ DWORD cbInDataSize,
        /* [length_is][size_is][out] */ __RPC__out_ecount_part(dwOutDataSize, pdwActualDataSize ? *pdwActualDataSize : dwOutDataSize) BYTE *pOutData,
        /* [in] */ DWORD dwOutDataSize,
        /* [out] */ __RPC__out DWORD *pdwActualDataSize) = 0;
那么,我如何才能找到显示错误的实际问题,以及如何解决它呢

(我使用WIA1,因为WIA2找不到设备)

在winnt.h中定义如下:

#if defined(_WIN32) || defined(_MPPC_)

// Win32 doesn't support __export

#ifdef _68K_
#define STDMETHODCALLTYPE       __cdecl
#else
#define STDMETHODCALLTYPE       __stdcall
#endif
#define STDMETHODVCALLTYPE      __cdecl

#define STDAPICALLTYPE          __stdcall
#define STDAPIVCALLTYPE         __cdecl

#else

#define STDMETHODCALLTYPE       __export __stdcall
#define STDMETHODVCALLTYPE      __export __cdecl

#define STDAPICALLTYPE          __export __stdcall
#define STDAPIVCALLTYPE         __export __cdecl

#endif
编辑1:

GetExtendedErrorInfo
现在返回NotImplemented错误(但这对我来说目前并不重要)

更大的问题是

ppWiaExtra->Escape
返回
E_FAIL
并且该项未指定,我认为这又是
指针的问题,或者是我使用
sizeof

这条线不对;您不能只是强制转换指针以获得不同的COM接口。这就是为什么:


如果您正在调用的函数具有
\uu stdcall
调用约定,并且您的代码正在使用
\uuu cdecl
约定,则通常会发生此错误,反之亦然。您正在调用的函数可以是虚拟的证据在哪里?STDMETHODCALLTYPE的定义如下(在winnt.h中)#ifdef 68K#define STDMETHODCALLTYPE uu cdecl#else#define STDMETHODCALLTYPE u stdcall#endif#define STDMETHODCALLTYPE u cdecl#和"virtual(转义方法的所有代码)我可以在wia_lh.h或wia_xp.h中找到(参数完全相同)谢谢你修复了它-现在我知道hr6(GetExtendedErrorInfo)没有实现(对我来说不是很重要),但是Escape返回E_FAIL-这是一个未指定的错误,可能是sizeof()的一些问题?你根本不应该使用sizeof。API要求在每个参数中输入字节数(分别为37和4),而不是以字节为单位输入指针的大小。我建议花一些时间阅读C++中使用Win32 API的例子,以了解常见模式是如何工作的。在微软文档页旁边的信息中,没有关于WiaC++的有用信息。这也不能帮助一些“未知的失败”——也运行实际运行的例子,并且开源是非常罕见的。我说“在C++中使用Win32 API是通用的”;到目前为止,您遇到的问题都不是WIA特有的。查询接口和数组作为指针加上长度是Win32中非常常见的模式。
ppWiaExtra->Escape
IWiaItemExtras* ppWiaExtra = (IWiaItemExtras*)ppWiaDevice;
IWiaItemExtras* ppWiaExtra;
HRESULT result = ppWiaDevice->QueryInterface(IID_PPV_ARGS(&ppWiaExtra));