前言
CANoe是目前汽车电子开发中差常用的工具,因为其封闭性(Vector独有),开发的时候,有很多局限性;这个时候我们可以通过C++的强大来弥补CAPL的不足,我们可以通过C++封装一个动态链接库(DLL),然后我们在CAPL中引用即可,下面我们就怎么创建一个DLL,简单介绍下Vector 官方Demo
1,软件版本:
- CANoe使用的是 11.0版本
- VS 是 VS 2019 社区版
2,一般的C++创建的DLL在CAPL中是无法使用的,必须遵循CAPL的语法创建的才可以正常使用。 在CANoe/CANalyzer 的安装包中, 有Vector 的官方Demo,我们可以仿照着去创建我们的DLL。
CANoe 11.0版本 demo的安装位置:
说明:
- VS 2017 Project 生成的平台是 X 64版本,本人用VS 2019直接打开,直接编译生成DLL,不可用,不知为何,就放弃了 ,
- VS 2013 Project 生成的平台是 32 版本,直接生成可用
3,使用VS打开上面截图中的 VS 2013 Project , 我们直接打开capldll.cpp文件,然后定位到下面代码的地方:
// ============================================================================
// CAPL_DLL_INFO_LIST : list of exported functions
// The first field is predefined and mustn't be changed!
// The list has to end with a {0,0} entry!
// New struct supporting function names with up to 50 characters
// ============================================================================
CAPL_DLL_INFO4 table[] = {
{CDLL_VERSION_NAME, (CAPL_FARCALL)CDLL_VERSION, "", "", CAPL_DLL_CDECL, 0xabcd, CDLL_EXPORT },
{"dllInit", (CAPL_FARCALL)appInit, "CAPL_DLL","This function will initialize all callback functions in the CAPLDLL",'V', 1, "D", "", {"handle"}},
{"dllEnd", (CAPL_FARCALL)appEnd, "CAPL_DLL","This function will release the CAPL function handle in the CAPLDLL",'V', 1, "D", "", {"handle"}},
{"dllSetValue", (CAPL_FARCALL)appSetValue, "CAPL_DLL","This function will call a callback functions",'L', 2, "DL", "", {"handle","x"}},
{"dllReadData", (CAPL_FARCALL)appReadData, "CAPL_DLL","This function will call a callback functions",'L', 2, "DL", "", {"handle","x"}},
{"dllPut", (CAPL_FARCALL)appPut, "CAPL_DLL","This function will save data from CAPL to DLL memory",'V', 1, "D", "", {"x"}},
{"dllGet", (CAPL_FARCALL)appGet, "CAPL_DLL","This function will read data from DLL memory to CAPL",'D', 0, "", "", {""}},
{"dllVoid", (CAPL_FARCALL)voidFct, "CAPL_DLL","This function will overwrite DLL memory from CAPL without parameter",'V', 0, "", "", {""}},
{"dllPutDataOnePar", (CAPL_FARCALL)appPutDataOnePar, "CAPL_DLL","This function will put data from CAPL array to DLL",'V', 1, "B", "\001", {"datablock"}},
{"dllGetDataOnePar", (CAPL_FARCALL)appGetDataOnePar, "CAPL_DLL","This function will get data from DLL into CAPL memory",'V', 1, "B", "\001", {"datablock"}},
{"dllPutDataTwoPars", (CAPL_FARCALL)appPutDataTwoPars,"CAPL_DLL","This function will put two datas from CAPL array to DLL",'V', 2, "DB", "\000\001", {"noOfBytes","datablock"}},// number of pars in octal format
{"dllGetDataTwoPars", (CAPL_FARCALL)appGetDataTwoPars,"CAPL_DLL","This function will get two datas from DLL into CAPL memory",'V', 2, "DB", "\000\001", {"noOfBytes","datablock"}},
{"dllAdd", (CAPL_FARCALL)appAdd, "CAPL_DLL","This function will add two values. The return value is the result",'L', 2, "LL", "", {"x","y"}},
{"dllSubtract", (CAPL_FARCALL)appSubtract, "CAPL_DLL","This function will substract two values. The return value is the result",'L', 2, "LL", "", {"x","y"}},
{"dllSupportLongFunctionNamesWithUpTo50Characters", (CAPL_FARCALL)appLongFuncName, "CAPL_DLL","This function shows the support of long function names",'D', 0, "", "", {""}},
{"dllAdd63Parameters", (CAPL_FARCALL)appAddValues63, "CAPL_DLL", "This function will add 63 values. The return value is the result",'L', 63, "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL", "", {"val01","val02","val03","val04","val05","val06","val07","val08","val09","val10","val11","val12","val13","val14","val15","val16","val17","val18","val19","val20","val21","val22","val23","val24","val25","val26","val27","val28","val29","val30","val31","val32","val33","val34","val35","val36","val37","val38","val39","val40","val41","val42","val43","val44","val45","val46","val47","val48","val49","val50","val51","val52","val53","val54","val55","val56","val57","val58","val59","val60","val61","val62","val63"}},
{"dllAdd64Parameters", (CAPL_FARCALL)appAddValues64, "CAPL_DLL", "This function will add 64 values. The return value is the result",'L', 64, {SixtyFourLongPars}, "", {"val01","val02","val03","val04","val05","val06","val07","val08","val09","val10","val11","val12","val13","val14","val15","val16","val17","val18","val19","val20","val21","val22","val23","val24","val25","val26","val27","val28","val29","val30","val31","val32","val33","val34","val35","val36","val37","val38","val39","val40","val41","val42","val43","val44","val45","val46","val47","val48","val49","val50","val51","val52","val53","val54","val55","val56","val57","val58","val59","val60","val61","val62","val63","val64"}},
{0, 0}
};
关键参数说明
1,这是CAPL编程DLL的唯一不同点就是需要配置这个Table,搞定这个,CAPL的DLL编程和一般C++的DLL编程有没什么区别,这里其它参数逗号理解,可能就倒数第二个参数 “参数维度”这个特殊一点,下面举例说明下。
2,Table的数据类型参数简称和CAPL,C++数据类型对照图。
3,实例 - 1 (参数是标量)
当参数是标量时,下面的这个例子,没有返回值,所以函数返回值是“V”,有一个 unsigned long 标量,所以对应的参数类型是“D”,因为是标量,所以维度是0,即“\000”
4,实例 - 2(参数是数组)
这个实例函数没有返回值,返回值参数是“V”;前后有两个参数,第一个是unsigned long 标量,所以对应的参数类型是“D”,因为是标量,所以维度是0,即“\000” ;第二个参数是一维unsigned char数组,所以对应的参数类型是“B”,维度参数是“\001” ;
5,实例 - 3 (参数是引用*)
-在从CAPL dll导出的函数中也可以使用引用参数。因此必须将函数的参数声明为实际数据类型上的指针。之后,从CAPL导出表中表示数据类型的字符中减去128。然后函数接收传递的变量的地址作为参数的值
总结
- 如上就是这篇博客的内容了,CAPL虽然较为封闭,但是留的编程接口很多,可以C++,C#,.NET,Python等等,如果能够很好的用好DLL编程,可以把你的核心算法或者脚本封装在DLL中,在给客户提供cases是,可以有效保护你的代码安全;而且C++的函数库要比CAPL强大的多。
- 好记性,不如烂笔头,技术探索路漫漫,携手志同道合之人上下求索是件很快乐的事。
- 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。