WIN10 +VS2017调用zolozVerify后摄像头显示白屏
结论
摄像头本身大概率没有故障。官方程序包中的 testmain.exe 可以正常显示画面,说明摄像头、驱动和 SDK 的基本采集功能都能正常工作。
白屏更可能是业务程序的集成环境与 testmain.exe 不一致。建议重点检查以下几项:
- SDK 依赖的 DLL、模型或资源文件没有完整部署。
- 程序的工作目录不正确,导致 SDK 无法通过相对路径加载资源。
- 工程平台与 SDK 位数不一致,例如程序是 x64,而 SDK 是 x86。
- Debug/Release 运行库或 Visual C++ Runtime 不匹配。
zolozVerify没有在 SDK 要求的线程或消息循环环境中调用。- 显卡驱动、远程桌面或硬件加速导致预览窗口渲染失败。
优先检查运行目录
不要只把 SDK 的几个 DLL 复制到业务程序目录。可以先让业务程序在与 testmain.exe 完全相同的目录结构中运行,保留程序包中的 DLL、配置文件、模型文件、图片和其他资源目录。
需要特别注意的是,Visual Studio 启动程序时,当前工作目录不一定是 EXE 所在目录。如果 SDK 内部通过相对路径读取文件,就可能出现窗口已经打开、摄像头也完成初始化,但预览区域无法正常渲染的情况。
可以先在项目属性中设置:
配置属性
→ 调试
→ 工作目录
→ $(TargetDir)
也可以在初始化 SDK 前,将当前目录切换到 EXE 所在目录:
#include <Windows.h>
#include <string>
static bool SetWorkingDirectoryToExePath()
{
wchar_t exePath[MAX_PATH] = {};
DWORD length = GetModuleFileNameW(nullptr, exePath, MAX_PATH);
if (length == 0 || length >= MAX_PATH) {
return false;
}
std::wstring directory(exePath, length);
const std::wstring::size_type pos = directory.find_last_of(L"\\/");
if (pos == std::wstring::npos) {
return false;
}
directory.resize(pos);
return SetCurrentDirectoryW(directory.c_str()) != FALSE;
}
int main()
{
if (!SetWorkingDirectoryToExePath()) {
return -1;
}
// 完成 SDK 初始化后,再调用:
// zoloz::smile_to_pay::zolozVerify(...);
return 0;
}
这里没有展开 zolozVerify 的参数,因为不同程序包提供的函数签名可能不同。具体参数应以当前 SDK 附带的头文件和示例代码为准。
对比工程平台和运行库
检查业务工程与 testmain.exe 使用的体系结构是否一致:
配置属性
→ 常规
→ 平台工具集:Visual Studio 2017 (v141)
配置管理器
→ 活动解决方案平台:Win32 或 x64
不能因为操作系统是 64 位,就直接把工程设置为 x64。如果 SDK 只提供 32 位 DLL,业务程序也必须编译为 Win32,反之亦然。
还要检查运行库设置:
配置属性
→ C/C++
→ 代码生成
→ 运行库
建议先使用 Release 配置验证,并按照 SDK 示例工程的设置选择 /MD 或 /MDd。不同位数或不同编译配置的 DLL 不要混用。
可以通过 Visual Studio 的模块窗口、dumpbin /headers 或依赖检查工具确认 EXE 和 DLL 的架构:
dumpbin /headers your_app.exe | findstr machine
dumpbin /headers zoloz_sdk.dll | findstr machine
其中 zoloz_sdk.dll 只是示意名称,需要替换为程序包中的实际 DLL。
检查资源和依赖文件
将业务程序的运行目录与 zoloz_smile2pay_release_200724\bin 对比,重点检查:
- SDK 主 DLL 是否齐全。
- 第三方图像处理、渲染和摄像头相关 DLL 是否齐全。
- 配置、模型、证书或资源目录是否保留了原有层级。
- DLL 是否被 Windows 安全策略拦截。
- PATH 中是否存在同名旧版 DLL,导致程序加载了错误版本。
如果直接复制整个 bin 目录后问题消失,通常说明原因在于部署缺失或路径错误。确认原因后,再逐项整理正式发布需要的文件。开始排查时不建议只挑选看起来“有用”的 DLL。
可以使用 Process Monitor 过滤业务程序,观察调用 zolozVerify 时是否大量出现以下记录:
NAME NOT FOUND
PATH NOT FOUND
BAD IMAGE
同时对比 testmain.exe 和业务程序实际加载的 DLL 路径。即使 DLL 名称相同,从不同目录加载也可能产生不同结果。
检查调用线程和消息循环
如果 SDK 示例是在主线程或 GUI 线程中调用 zolozVerify,业务程序也应先采用相同的调用方式。除非当前 SDK 文档明确说明支持,否则不要在普通工作线程中直接创建刷脸窗口。
例如,业务处理可以放在工作线程中,但 SDK 界面调用应投递回窗口线程:
constexpr UINT WM_START_ZOLOZ_VERIFY = WM_APP + 1;
LRESULT MainWindow::WndProc(
HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message) {
case WM_START_ZOLOZ_VERIFY:
// 使用当前 SDK 头文件定义的真实参数调用。
// zoloz::smile_to_pay::zolozVerify(...);
return 0;
default:
return DefWindowProcW(hwnd, message, wParam, lParam);
}
}
// 在其他线程中请求启动时:
PostMessageW(mainWindowHandle, WM_START_ZOLOZ_VERIFY, 0, 0);
如果业务程序是控制台程序,还要确认 SDK 是否依赖 Windows 消息循环。窗口能够出现,不代表消息循环和渲染线程一定正常。
排查渲染环境
确认依赖、路径和工程配置一致后,再检查图形渲染环境:
- 在本机物理桌面运行,暂时不要通过远程桌面测试。
- 更新或回退显卡驱动后重新测试。
- 确认刷脸界面不是由 Windows 服务或 Session 0 启动的。
- 确认程序没有启用与示例不同的兼容模式。
- 在双显卡设备上,分别指定集成显卡和独立显卡测试。
- 如果 SDK 提供软件渲染或关闭硬件加速的正式配置项,可以按照对应版本的文档进行验证,不要自行猜测配置参数。
“窗口白屏”有时只是预览控件没有完成绘制,并不代表摄像头没有采集到图像。需要结合 SDK 日志,分别判断采集初始化和渲染初始化是否成功。
推荐排查顺序
- 将业务 EXE 放入官方
bin目录直接运行。 - 把工作目录设置为
$(TargetDir)。 - 确认 Win32/x64 与 SDK 完全一致。
- 使用与示例工程一致的 Release、运行库和工具集配置。
- 对比业务程序与
testmain.exe加载的 DLL 和资源路径。 - 在主线程或 GUI 线程中调用
zolozVerify。 - 检查 SDK 日志以及 Process Monitor 中的文件加载失败记录。
- 最后排查远程桌面、显卡驱动和硬件加速问题。
如果把业务 EXE 放入官方 bin 目录后仍然白屏,而 testmain.exe 在同一目录中正常运行,问题通常集中在工程位数、运行库、调用线程或初始化顺序。若业务 EXE 放入该目录后恢复正常,则基本可以确定是 DLL、资源部署或工作目录的问题。
备注:内容仅供参考。
