大恒Galaxy SDK MFC开发(1):枚举、打开、开始/停止采集基础流程(无画面版)
- [一、 前言](#一、 前言)
- 二、开发环境
- 三、工程配置步骤(新手必看,补充完善)
- [四、 核心流程(重中之重)](#四、 核心流程(重中之重))
- [五、 核心代码(精简版,只贴关键片段)](#五、 核心代码(精简版,只贴关键片段))
-
- [1. 相机枚举(填充下拉框)](#1. 相机枚举(填充下拉框))
- [2. 打开/关闭相机](#2. 打开/关闭相机)
- [3. 采集启停](#3. 采集启停)
- 六、功能说明
- 七、关键注意事项(新手必看)
- 八、常见问题排查(补充,新手必备)
- 总结
一、 前言
本文基于大恒Galaxy SDK,以MFC对话框工程(CPP_MFC_Daheng_01_Base)为载体,实现相机最基础的操作流程,核心聚焦「流程正确性」,不含图像取图、显示逻辑,代码极简、注释清晰,适合刚接触大恒相机开发的新手,可直接作为项目基础框架复用。
核心功能:SDK初始化/释放 + 相机枚举(下拉选择) + 相机打开/关闭 + 采集启停 + 日志打印,全程无图像处理,专注跑通基础流程、避免资源泄露。
补充说明:本文工程仅实现"流程跑通",不涉及图像数据获取与显示,重点解决新手"相机打不开、采集启动失败、资源泄露"三大核心问题,是工业视觉开发的入门基础。
二、开发环境
-
开发工具:Visual Studio(2010/2026均可)
-
项目类型:MFC 对话框应用程序(使用多字节字符集)
-
相机SDK:大恒Galaxy SDK(安装GalaxySDK,建议安装最新版本,兼容更多相机型号)
-
核心依赖:GXDevice.lib(SDK核心库,根据编译平台选择x64/x86版本)
-
运行环境:Windows 10/11(32位/64位均可,与编译版本对应)
补充:GalaxySDK下载地址( 大恒官网):(进入官网下载中心→软件下载→windows第一个就行),安装时一路下一步,默认安装路径为:C:\Program Files\Daheng Imaging\GalaxySDK(64位系统)。

三、工程配置步骤(新手必看,补充完善)
新建MFC对话框工程后,需完成SDK配置才能正常编译运行,步骤如下:
-
打开工程属性(右键工程 → 属性);
-
配置包含目录:在「配置属性 → C/C++ → 常规 → 附加包含目录」中,添加大恒Galaxy SDK的「Include」文件夹路径(如:C:\Program Files\Daheng Imaging\GalaxySDK\Development\C++ SDK\inc
);
-
配置库目录:在「配置属性 → 链接器 → 常规 → 附加库目录」中,添加SDK的「Lib」文件夹路径(如:C:\Program Files\Daheng Imaging\GalaxySDK\Development\C++ SDK\lib\x64,根据编译平台选择x64或x86);
-
配置附加依赖项:在「配置属性 → 链接器 → 输入 → 附加依赖项」中,添加「GxIAPICPPEx.lib」(Debug版本、Release版本同样适用);
-
确认字符集:在「配置属性 → 高级 → 字符集」中,选择【使用多字节字符集】(重点!如果选择"使用 Unicode 字符集",会导致SDK相关函数报错)
四、 核心流程(重中之重)
工业相机基础开发的核心链路,也是本文全部内容,无需多余操作:
- 初始化 SDK
cpp
IGXFactory::GetInstance().Init();
必须第一个调用,用于初始化相机底层库。
- 枚举设备
cpp
gxdeviceinfo_vector vectorDeviceInfo;
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
扫描所有连接的相机,存入列表。
- 打开相机(通过 SN 打开)
cpp
CGXDevicePointer ObjDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(...)
稳定、安全、不会打开错设备。
- 开启采集(最重要)
cpp
ObjStreamPtr->StartGrab();
ObjFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
这两句必须一起调用:
StartGrab ():开启流通道
AcquisitionStart:让相机开始发图
- 停止采集
cpp
ObjFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
ObjStreamPtr->StopGrab();
顺序不能反,否则会报错。
- 释放资源
cpp
//释放资源
//关闭流
ObjStreamPtr->Close();
// 关闭设备
ObjDevicePtr->Close();
//反初始化库
IGXFactory::GetInstance().Uninit();
补充:流程顺序不可颠倒,尤其是"停止采集→关闭相机→释放SDK",颠倒会导致资源泄露、程序崩溃,日志会打印对应错误信息,便于排查。
五、 核心代码(精简版,只贴关键片段)
1. 相机枚举(填充下拉框)
cpp
if (!vectorDeviceInfo.empty())
vectorDeviceInfo.clear();
//枚举相机设备
IGXFactory::GetInstance().UpdateDeviceList(1000, vectorDeviceInfo);
CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST_CAMERA);
pList->ResetContent();
for(int i=0; i<vectorDeviceInfo.size(); i++)
{
CString str;
CA2AEX<128> aBuf(vectorDeviceInfo[i].GetModelName());
str.Format(_T("[%d] %s"), i,(LPCSTR)aBuf);
//str.Format(_T("[%d] %s"), i, CA2T(vectorDeviceInfo[i].GetModelName()));
pList->AddString(str);
}
if (vectorDeviceInfo.size() <= 0)
{
AddLog(_T("未发现设备!"));
//MessageBox("未发现设备!");
return;
}
AddLog(_T("相机枚举完成"));
2. 打开/关闭相机
cpp
//相机选中打开函数
void OpenCam()
{
bool bIsDeviceOpen = false; ///< 设备是否打开标志
bool bIsStreamOpen = false; ///< 设备流是否打开标志
try
{
CListBox* pList = (CListBox*)GetDlgItem(IDC_LIST_CAMERA);
int nSel = pList->GetCurSel();
if(nSel < 0)
{
AddLog(_T("请选择相机"));
return;
}
//打开设备
m_objDevicePtr = IGXFactory::GetInstance().OpenDeviceBySN(vectorDeviceInfo[nSel].GetSN(),GX_ACCESS_EXCLUSIVE);
bIsDeviceOpen = true;
m_objFeatureControlPtr = m_objDevicePtr->GetRemoteFeatureControl();
//判断设备流是否大于零,如果大于零则打开流
int nStreamCount = m_objDevicePtr->GetStreamCount();
if (nStreamCount > 0)
{
m_objStreamPtr = m_objDevicePtr->OpenStream(0);
m_objStreamFeatureControlPtr = m_objStreamPtr->GetFeatureControl();
bIsStreamOpen = true;
}
else
{
MessageBox("未发现设备流!");
}
// 建议用户在打开网络相机之后,根据当前网络环境设置相机的流通道包长值,
// 以提高网络相机的采集性能,设置方法参考以下代码。
GX_DEVICE_CLASS_LIST objDeviceClass = m_objDevicePtr->GetDeviceInfo().GetDeviceClass();
if(GX_DEVICE_CLASS_GEV == objDeviceClass)
{
// 判断设备是否支持流通道数据包功能
if(true == m_objFeatureControlPtr->IsImplemented("GevSCPSPacketSize"))
{
// 获取当前网络环境的最优包长值
int nPacketSize = m_objStreamPtr->GetOptimalPacketSize();
// 将最优包长值设置为当前设备的流通道包长值
m_objFeatureControlPtr->GetIntFeature("GevSCPSPacketSize")->SetValue(nPacketSize);
}
}
m_bIsOpen = true;
// 打印日志
CString log;
log.Format(_T("第%d个相机打开%s成功 "), nSel, CString(vectorDeviceInfo[nSel].GetModelName()));
AddLog(log);
}
catch (CGalaxyException& e)
{
//判断设备流是否已打开
if (bIsStreamOpen)
{
m_objStreamPtr->Close();
}
//判断设备是否已打开
if (bIsDeviceOpen)
{
m_objDevicePtr->Close();
}
AddLog(_T("相机打开失败"));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
catch (std::exception& e)
{
//判断设备流是否已打开
if (bIsStreamOpen)
{
m_objStreamPtr->Close();
}
//判断设备是否已打开
if (bIsDeviceOpen)
{
m_objDevicePtr->Close();
}
AddLog(_T("相机打开失败"));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
}
//相机关闭采集
void CloseCam()
{
//先调用停止采集
StopSnap();
if(m_bIsOpen)
{
try
{
//关闭流对象
m_objStreamPtr->Close();
}
catch(CGalaxyException &e)
{
AddLog(_T("相机流关闭失败"));
AddLog(_T(e.what()));
MessageBox(e.what());
}
try
{
//关闭设备
m_objDevicePtr->Close();
}
catch(CGalaxyException &e)
{
AddLog(_T("相机关闭失败"));
AddLog(_T(e.what()));
MessageBox(e.what());
}
m_bIsOpen = false;
AddLog(_T("相机关闭完成"));
}
}
3. 采集启停
cpp
//相机开始采集函数
void StartSnap()
{
try
{
if(!m_bIsSnap)
{
//开启流层通道
m_objStreamPtr->StartGrab();
//发送开采命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStart")->Execute();
m_bIsSnap = true;
AddLog(_T("相机开始采集..."));
return;
}
AddLog(_T("相机已经开始采集..."));
}
catch (CGalaxyException& e)
{
AddLog(_T("相机开始采集失败..."));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
catch (std::exception& e)
{
AddLog(_T("相机开始采集失败..."));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
}
//相机停止采集
void StopSnap()
{
try
{
if(m_bIsSnap)
{
//发送停采命令
m_objFeatureControlPtr->GetCommandFeature("AcquisitionStop")->Execute();
//关闭流层通道
m_objStreamPtr->StopGrab();
m_bIsSnap = false;
AddLog(_T("相机停止采集..."));
}
}
catch (CGalaxyException& e)
{
AddLog(_T("相机停止采集失败..."));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
catch (std::exception& e)
{
AddLog(_T("相机停止采集失败..."));
AddLog(_T(e.what()));
MessageBox(e.what());
return;
}
}
六、功能说明

-
界面控件:ListBox(相机选择)、5个按钮(刷新、打开、关闭、开始采集、停止采集)、Edit(日志显示)
-
核心逻辑:仅实现相机基础操作流程,无任何图像取图、显示、处理代码
-
日志功能:实时打印操作状态、错误信息,便于调试;写入日志文件,方便分析
-
安全机制:避免重复打开相机、重复启停采集,程序退出自动释放所有资源
-
兼容性:适配大恒主流相机型号,只要SDK安装正确,无需修改核心代码即可使用
七、关键注意事项(新手必看)
-
必须先停止采集,再关闭相机,否则会导致资源泄露、程序崩溃;
-
SDK初始化(Init)和释放(Uninit)必须成对出现,放在程序启动和退出时;
-
工程配置时,需添加SDK的Include目录、Lib目录,以及附加依赖项GxIAPICPPEx.lib;
-
枚举相机时,超时时间建议设置为1000ms(1秒),过短可能导致枚举失败;
-
打开相机后,禁止点击"刷新"按钮,避免相机句柄冲突,导致程序崩溃;
-
日志编辑框需设置为"多行、允许滚动",否则日志会被遮挡,无法查看完整调试信息。
八、常见问题排查(补充,新手必备)
-
问题1:编译报错"无法打开包括文件: "GalaxyIncludes.h"" → 解决方案:检查工程属性中"附加包含目录"是否添加SDK的Include文件夹;
-
问题2:链接报错"无法解析的外部符号" → 解决方案:检查"附加库目录"是否正确,"附加依赖项"是否添加GxIAPICPPEx.lib,以及编译平台(x64/x86)与SDK版本一致;
-
问题4:枚举相机显示"未检测到任何相机设备" → 解决方案:检查相机供电、连接是否正常(相机灯是否为绿色),打开驱动自带的GalaxyView软件确认相机能被识别,重启相机后重新运行程序;
总结
本文工程(CPP_MFC_Daheng_01_Base)定位为「大恒相机MFC开发基础模板」,核心是跑通"枚举-打开-采集-关闭"的完整流程,不涉及复杂的图像处理,适合新手入门。
配套资源下载(VS工程直接用)
本文配套完整VS2010控制台工程,已配置好SDK,无需手动配置,下载后直接用VS2010打开(2026通过测试),编译运行即可。