CANoe中的DLL编程


前言

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的安装位置:
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强大的多。

在这里插入图片描述

在这里插入图片描述

  • 好记性,不如烂笔头,技术探索路漫漫,携手志同道合之人上下求索是件很快乐的事。
  • 如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。
CAPL(通信应用程序接口语言)是一种用于开发汽车网络通信系统的脚本语言。在CANoe,我们可以使用CAPL编写脚本来控制仿真器和与其他节点进行通信。以下是一个使用CAPL编写的CANoe实例: 假设我们有一个CAN网络,包括一个ECU(电子控制单元)和一个仿真器。我们希望通过CANoe向ECU发送一个开启车灯的信号。 在CAPL脚本,我们可以首先定义一个节点,其属性为ECU。然后,我们可以使用定时器来定时发送CAN消息。 ```c variables { message msg; node ecu NodeName = { nodetype = ECU; address = 0x01; }; } on preStart { setTimer(1, 1000); // 设置定时器,每秒触发一次 } on timer(1) { setSignal(msg, "LightStatus", 1); // 设置CAN消息的信号值 ecu.SEND(msg); // 发送CAN消息 } ``` 在上述脚本,我们首先定义了一个名为`msg`的CAN消息。然后,我们创建了`ecu`节点,并将其属性设为ECU,并指定了地址为0x01。 在`on preStart`事件,我们设置了一个名为1的定时器,每隔1秒触发一次。 在`on timer(1)`事件,我们将CAN消息`msg`的信号`LightStatus`设置为1,表示开启车灯。然后,我们使用`ecu.SEND(msg)`将CAN消息发送给ECU。 通过这个CAPL脚本,我们可以实现在CANoe仿真向ECU发送开启车灯的信号。这个例子展示了CAPLCANoe的应用,它可以帮助我们模拟和测试汽车网络通信系统。为了更好地理解CAPL编程CANoe的功能,可以进一步了解CAPL语言的语法和CANoe仿真器的具体使用方法。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚂蚁小兵

慢慢长夜磨一章好文章,费烟!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值