【问题标题】:WIA Run-Time Check Failure #0 C++ (Windows Image Acquisition)WIA 运行时检查失败 #0 C++(Windows 图像采集)
【发布时间】:2020-02-27 15:00:14
【问题描述】:

我尝试使用 WIA 将数据发送到相机。 我需要用 C++ 开发它,所以我使用了https://docs.microsoft.com/en-us/windows/win32/wia/-wia-wia-tutorial 上的官方“教程” 我知道另一个使用 C# 的项目,我想在 C++ 上做同样的事情 (C# 项目在:https://github.com/pixeltris/SonyAlphaUSB

当我想使用Escape 方法https://docs.microsoft.com/en-us/windows/win32/api/wia_xp/nf-wia_xp-iwiaitemextras-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

我使用的方法与https://github.com/microsoft/Windows-classic-samples/blob/master/Samples/Win7Samples/multimedia/wia/wiassamp/wiassamp.cpp上的示例代码相同

转义方法是:

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 找不到设备)

STDMETHODCALLTYPE 

在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

现在返回 Not Implemented Error(但这对我来说目前并不重要)

更大的问题是

ppWiaExtra->Escape

返回 E_FAIL 并且那个未指定,我认为这又是一些 pointer 问题或我使用 sizeof 的问题

【问题讨论】:

  • 如果您调用的函数具有__stdcall 调用约定,并且您的代码使用__cdecl 约定,则通常会发生该错误,反之亦然。你调用的函数可以是virtual的证据在哪里?
  • STDMETHODCALLTYPE 定义如下(在 winnt.h 中)'#ifdef 68K #define STDMETHODCALLTYPE __cdecl #else #define STDMETHODCALLTYPE __stdcall #endif #define STDMETHODVCALLTYPE __cdecl' 和 'virtual '(Escape 方法的所有代码)我可以在 wia_lh.h 或 wia_xp.h 中找到(参数完全相同)

标签: c++ runtime-error wia


【解决方案1】:
IWiaItemExtras* ppWiaExtra = (IWiaItemExtras*)ppWiaDevice;

这行不正确;您不能只转换指针来获得不同的 COM 接口。这就是QueryInterface 的用途:

IWiaItemExtras* ppWiaExtra;
HRESULT result = ppWiaDevice->QueryInterface(IID_PPV_ARGS(&ppWiaExtra));

【讨论】:

  • 谢谢你修复它 - 现在我知道 hr6 (GetExtendedErrorInfo) 没有实现(对我来说不是那么重要)但是 Escape 正在返回 E_FAIL - 这是一个未指定的错误,可能是 sizeof() 的一些问题?
  • 您根本不应该使用 sizeof。 API 询问每个参数中的字节数(分别为 37 和 4),而您传递的是指针的大小(以字节为单位)。我建议花一些时间阅读在 C++ 中使用 Win32 API 的一般示例,以了解常见模式的工作原理。
  • 嗯,除了 Microsoft 文档页面上的信息之外,我没有任何关于 WIA C++ 的有用信息。这对于一些“未知故障”也无济于事——而且运行实际有效且开源的示例也非常罕见。
  • 我说的是“一般在 C++ 中使用 Win32 API”;到目前为止,您遇到的所有问题都不是 WIA 特有的。 QueryInterface 和 array-as-pointer-plus-length 都是 Win32 中非常常见的模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 2011-09-01
相关资源
最近更新 更多