目录
- 2.4.1 数据结果:通过流程输出或模块输出获取数据结果的方法
- 2.4.2 流程运行:所有流程运行结束的回调方法
- 2.4.3 模块回调:所有模块运行结束的回调方法
- 2.4.4 加密狗回调:获取加密狗状态的回调方法
- 2.4.5 方案加载:方案加载结束的回调方法
- 2.4.6 模块回调:指定模块运行结束的回调方法
- 2.4.7 模块回调:禁用模块结果回调的方法
- 2.4.8 通讯回调:通讯设备状态和接受数据的回调方法
2.4.1 数据结果:通过流程输出或模块输出获取数据结果的方法
描述
环境:VM4.0.0 + VS2015及以上
现象:方案或流程运行执行之后,就可以获取结果(建议将结果获取写在回调函数里),可以通过获取渲染结果和数据结果,渲染结果通过绑定渲染控件进行显示,数据结果分为整型、浮点型、字符串型和图像型等等,VM二次开发如何获取数据结果?
解答
数据结果的获取可以通过流程的输出或者模块的输出,推荐使用通过流程的输出,符合高内聚低耦合的思想,详细介绍如下所示:
1 通过流程的输出获取数据结果
1.1 流程配置-输出设置
1.2 获取整型、浮点型、字符串型数据
C#
VmProcedure vmprocess = (VmProcedure)VmSolution.Instance["流程1"];
string str = vmprocess.GetIntOutputResult("out").pIntValue[0].ToString();
string str1 = vmprocess.GetFloatOutputResult("out0").pFloatValue[0].ToString();
string str2 = vmprocess.GetStringOutputResult("out1").astStringValue[0].strValue;C#
// 流程拿结果,c从界面层获取的方法,适用于高内存场景
string str2 = ((ImvsSdkDefine.IMVS_MODULE_STRING_VALUE_EX)(vmProcess["out1.Value"] as Array).GetValue(0)).strValue.ToString();//字符串型结果
string str1 = ((vmProcess["out0.Value"] as Array).GetValue(0)).ToString();//浮点型结果
1.3 获取图像数据
流程输出设置中输出IMAGE类型的图像数据,不能通过前面参数名称image拿取,需要通过Imageout0,ImageWidthout0,ImageHeightout0,ImagePixelFormatout0,这四个参数进行获取。示例代码和图像如下:
C#
VmProcedure VmProcess = (VmProcedure)VmSolution.Instance["流程1"];//实例化流程1
ImageResultInfo resultInfo0 =VmProcess.GetImageOutputResult("Imageout0");
IntResultInfo resultInfo1 =VmProcess.GetIntOutputResult("ImageWidthout0");
IntResultInfo resultInfo2 =VmProcess.GetIntOutputResult("ImageHeightout0");
IntResultInfo resultInfo3 =VmProcess.GetIntOutputResult("ImagePixelFormatout0");
byte[] imageData=resultInfo0.pstImageValue[0].pData;
2 通过模块的输出获取数据结果
2.1 获取模块的浮点型数据
C#
IMVSCircleFindModuCs.IMVSCircleFindModuTool circleTool=(IMVSCircleFindModuCs.IMVSCircleFindModuTool)VmSolution.Instance["流程1.圆查找1"];
//只调用一次circleTool.ModuResult表示只从底层拿一次结果,适用于高内存场景
var circleToolResult = circleTool.ModuResult;
string circleX = circleToolResult.OutputCircle.CenterPoint.X.ToString();
string circleY = circleToolResult.OutputCircle.CenterPoint.Y.ToString();
string circleR = circleToolResult.OutputCircle.Radius.ToString();
2.2 获取图像数据,针对有图像输出的模块
C#
//图像源模块
Using ImageSourceModuleCs;
ImageSourceModuleTool sourceImage=(ImageSourceModuleTool)VmSolution.Instance[“流程1.图像源1”];//实例化输出图形模块
Var sourceImageResult=sourceIamge.ModuResult.Imagedata;//只需要调用一次ModuResult,适用于高内存场景
byte[] imageData= sourceImageResult.ImageData;
int imagePixelformat= sourceImageResult.Pixelformat;C#
//输出图像模块
Using SaveImageCs;
SaveImageTool saveImage=(SaveImageTool)VmSolution.Instance[“流程1.输出图像1”];//实例化输出图像模块
Var saveImageResult=saveIamge.ModuResult.OutputImage;//只需要调用一次ModuResult,适用于高内存场景
byte[] imageData= saveImageResult.ImageData;
int imagePixelformat= saveImageResult.Pixelformat;
像素格式17301505为MONO8灰度图,像素格式 35127316为RGB24彩色图,需要注意的是输出图像模块的像素格式默认是RGB24,所以此时的输出图像模块的imagePixelformat为35127316。
问题根因
不熟悉如何获取数据结果
2.4.2 流程运行:所有流程运行结束的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象: 流程运行的触发方式有多种,无论哪种方式都可以进入回调函数,因此建议在回调函数中获取结果。
解答
1)流程运行的触发方式
2)所有流程运行结束的都会进入的回调函数,建议在回调函数里获取数据结果(参考2.4.1)和渲染结果(2.3.1),其中在回调函数里获取渲染结果时,需要使用委托(this.BeginInvoke)对控件进行绑定操作。
C#public Form1()
{InitializeComponent();//注册回调函数,流程运行状态回调VmSolution.OnWorkStatusEvent += VmSolution_OnWorkStatusEvent;
}
private void VmSolution_OnWorkStatusEvent(ImvsSdkDefine.IMVS_MODULE_WORK_STAUS workStatusInfo)
{if (workStatusInfo.nWorkStatus == 0 && workStatusInfo.nProcessID == 10000)//为0表示执行完毕,为1表示正在执行;10000表示流程1{//获取结果}
}C++
//类中声明变量和函数
IVmSolution* m_pVmSol;
IVmProcedure* m_pVmPrc;
static int __stdcall SolutionCallback(IN OutputPlatformInfo * const pstInputPlatformInfo, IN void * const pUser);
int SolutionCallbackFunc(IN OutputPlatformInfo * const pstInputPlatformInfo);//在初始化时用方案注册回调函数,这是所有流程运行结束都会自动进的回调函数
m_pVmSol->RegisterCallBack(SolutionCallback, this);//回调函数的实现方法,Demo为项目类名
int __stdcall Demo::SolutionCallback(IN OutputPlatformInfo * const pstInputPlatformInfo, IN void * const pUser)
{auto *pCtrlDemoThis = static_cast<Demo*>(pUser);int nRet = IMVS_EC_UNKNOWN;if (pCtrlDemoThis){nRet = pCtrlDemoThis->SolutionCallbackFunc(pstInputPlatformInfo);if (IMVS_EC_OK != nRet){return nRet;}}return IMVS_EC_OK;
}
int Demo::SolutionCallbackFunc(IN OutputPlatformInfo * const pstInputPlatformInfo)
{if (pstInputPlatformInfo->nInfoType == IMVS_ENUM_CTRLC_OUTPUT_PLATFORM_INFO_WORK_STATE){try {auto workstateInfo = static_cast<IMVS_PF_MODULE_WORK_STAUS*>(pstInputPlatformInfo->pData);if (workstateInfo->nWorkStatus == 0 && workstateInfo->nProcessID == 10000)//判断流程执行状态和流程ID{auto m_pVmPro = (IVmProcedure*)(*m_pVmSol)["流程1"];float info = m_pVmPro->GetResult()->GetOutputFloat("out").pFloatVal[0];}}catch (exception *e){TRACE(e->what());}}return 0;
}
问题根因
不熟悉流程运行结束的回调函数
2.4.3 模块回调:所有模块运行结束的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象:模块运行结束就会进入的回调函数
解答
所有模块运行结束就会进入的回调函数,代码如下:
C#//注册回调函数
VmSolution.OnModuleResultCallbackEvent += VmSolution_OnModuleResultCallbackEvent;
private void VmSolution_OnModuleResultCallbackEvent (ImvsSdkDefine.IMVS_MODULE_RESULT_INFO_LIST_EX_Data moduleResultExInfo)
{if (moduleResultExInfo.nModuleID == moduleID )//判断模块Id{if (moduleResultExInfo.nStatus == 1)//判断模块状态,1表示模块运行成功{//获取结果}}
}
问题根因
不熟悉所有模块运行结束的回调
2.4.4 加密狗回调:获取加密狗状态的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象:如何获取加密狗编号?
解答
建立ServerSDKManager.serverSDKManager.mSolutionManager.OnDongleCallBack事件,对事件中的moduleInfo进行处理。moduleInfo.nDongleStatus = 0代表加密狗状态正常,moduleInfo.strDongleType为加密狗编号。
C#ServerSDKManager.serverSDKManager.mSolutionManager.OnDongleCallBack += MSolutionManager_OnDongleCallBack;
private void MSolutionManager_OnDongleCallBack(ImvsSdkDefine.IMVS_DONGLE_INFO moduleInfo)
{if(moduleInfo.nDongleStatus == 0)//获取加密狗状态{string dogNum = System.Text.Encoding.Default.GetString(moduleInfo.strDongleType);//获取加密狗型号}else{MessageBox.Show("未检测到加密狗!");}
}
问题根因
不熟悉如何获取加密狗编号,从而判断是否插了加密狗
2.4.5 方案加载:方案加载结束的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象:方案加载结束进入的回调函数。
解答
首先,建立VmSolution.OnSolutionLoadEndEvent(方案加载结束)事件,对事件中的solutionLoadEndInfo进行判断,对方案的nStatus进行判定,其中0表示方案为空闲状态,可在其中获得方案加载结果,1表示方案处于忙碌状态。
C#VmSolution.OnSolutionLoadEndEvent += VmSolution_OnSolutionLoadEndEvent;
//方案加载成功private void VmSolution_OnSolutionLoadEndEvent
(ImvsSdkDefine.IMVS_SOLUTION_LOAD_END_INFO solutionLoadEndInfo)
{if (solutionLoadEndInfo.nStatus == 0)//0为方案加载成功{//这里可以插入相关函数}
}
提示:当方案中包含脚本模块或者深度学习模块,方案第一次执行耗时就会比较长,因此可以在方案加载成功后,静默执行一次,即在会回调函数里写静默执行语句:VmSolution.Instance.SilentExecute(true)。
问题根因
不熟悉方案加载结束的回调
2.4.6 模块回调:指定模块运行结束的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象:指定模块,在运行结束后进入回调函数。
解答
1)注册回调函数,模块被执行一次就会进该函数一次。
C#IVmModule module = (IMVSCircleFindModuTool)VmSolution.Instance["流程1.圆查找1"];
module.ModuleResultCallBackArrived += ModuleResultCallBackArrived;
2)回调函数,目前模块回调函数不是事件,因此无法快捷键自动补全代码,函数如下:
C#
private void ModuleResultCallBackArrived(object sender ,EventArgs e)
{IMVSCircleFindModuTool circleFind = (IMVSCircleFindModuTool)sender;float x = circleFind.ModuResult.OutputCircle.Radius;
}
问题根因
不熟悉指定模块运行结束的回调
2.4.7 模块回调:禁用模块结果回调的方法
描述
环境:VM4.0.0 + VS2015及以上
现象:为了提高内存利用率,禁用不必要的模块结果回调。
解答
禁用和启用模块结果回调,禁用之后将无法获取模块的结果,代码如下:
C#//禁用所有模块的回调
VmSolution.Instance.DisableModulesCallback();
//控制方案中回调,ID指模块ID,0是禁用,1是启用
ServerSDKManager.serverSDKManager.mModuleManager.CtrlCallBackModuResult(ID,0);
//启用所有回调
VmSolution.Instance.EnableModulesCallback();
问题根因
不熟悉相关接口的使用。
2.4.8 通讯回调:通讯设备状态和接受数据的回调方法
描述
环境:VM4.0.0 + VS2015及以上
现象:如何获取通讯设备的状态是开启还是关闭?如何获取通讯数据?
解答
- 获取通讯设备的状态
C#
//注册回调
VmSolution.OnCommunicationStatusCallBackEvent += VmSolution_OnCommunicationStatusCallBackEvent;private void VmSolution_OnCommunicationStatusCallBackEvent(ImvsSdkDefine.IMVS_COMMU_REPORT_DATA_INFO reportDataInfo)
{int nType = reportDataInfo.nType;byte[] btarr = ExternalCallHelper.IntPtr2Bytes(reportDataInfo.pData, reportDataInfo.nLen);int len = btarr.Length;string ID = btarr[1].ToString();//通讯设备IDstring Open = btarr[0].ToString();//开关状态,1表示开,0表示关
}
- 获取通讯数据
C#
//注册回调
VmSolution.OnCommunicationRecvCallBackEvent += VmSolution_OnCommunicationRecvCallBackEvent;
private void VmSolution_OnCommunicationRecvCallBackEvent(ImvsSdkDefine.IMVS_COMMU_REPORT_DATA_INFO reportDataInfo)
{string strMsg;try{int nType = reportDataInfo.nType;byte[] btarr = ExternalCallHelper.IntPtr2Bytes(reportDataInfo.pData, reportDataInfo.nLen);int len = btarr.Length;string ID = btarr[0].ToString();byte[] vs = new byte[len - 2];Array.Copy(btarr, 2, vs, 0, len - 2);string ReceiveData = System.Text.Encoding.Default.GetString(vs);strMsg = ID + "号设备接受到:" + ReceiveData;Logger.WriteLog(LogLevel.INFO, strMsg);}catch (VmException ex){strMsg = "读取通信数据失败. Error Code: " + Convert.ToString(ex.errorCode, 16);Logger.WriteLog(LogLevel.ERROR, strMsg);return;}
}
问题根因
不熟悉通讯相关的回调方法