我想使用 COM 从 Python 脚本运行 CAPL 函数来将帧发送到网络,正如我阅读第 2.7 章中的 文档 一样,需要有一个 OnInit 事件,所以我修改了 py_canoe 并实现了:
import sys
import logging
import pythoncom
import win32com.client
from time import sleep as wait
from logging import handlers
function2 = None
def DoEvents():
pythoncom.PumpWaitingMessages()
wait(.1)
def DoEventsUntil(cond):
while not cond():
DoEvents()
class CanoeApplicationEvents:
"""Handler for CANoe Application events"""
@staticmethod
def OnOpen():
print('canoe opened')
CANoe.CANOE_APP_OPENED = True
CANoe.CANOE_APP_CLOSED = False
@staticmethod
def OnQuit():
print('canoe closed')
CANoe.CANOE_APP_OPENED = False
CANoe.CANOE_APP_CLOSED = True
class CanoeMeasurementEvents:
"""Handler for CANoe Measurement events"""
@staticmethod
def OnStart():
CANoe.CANOE_MEAS_STARTED = True
CANoe.CANOE_MEAS_STOPPED = False
@staticmethod
def OnStop():
CANoe.CANOE_MEAS_STARTED = False
CANoe.CANOE_MEAS_STOPPED = True
@staticmethod
def OnInit():
global function2
function2 = CANoe.CAPLFunction(CANoe.__canoe_objects['CAPL'].GetFunction('function'))
class CANoe:
CANOE_APP_OPENED = False
CANOE_APP_CLOSED = False
CANOE_MEAS_STARTED = False
CANOE_MEAS_STOPPED = False
def __init__(self, py_canoe_log_dir=''):
self.log = logging.getLogger('CANOE_LOG')
self.__py_canoe_log_initialisation(py_canoe_log_dir)
self.wait_for_canoe_app_to_open = None
self.wait_for_canoe_meas_to_start = None
self.wait_for_canoe_meas_to_stop = None
self.wait_for_canoe_app_to_close = None
self.__diag_ecu_qualifiers_dictionary = dict()
self.__replay_blocks_obj_dictionary = dict()
self.__canoe_objects = dict()
self.__canoe_info = dict()
def open(self, canoe_cfg: str, visible=True, auto_save=False, prompt_user=False) -> None:
pythoncom.CoInitialize()
self.__canoe_objects['Application'] = win32com.client.Dispatch('CANoe.Application')
cav = self.__canoe_objects['Application'].Version
self.log.info(f'Dispatched Vector CANoe Application {cav.major}.{cav.minor}.{cav.Build}')
self.__canoe_objects['Application'].Visible = visible
self.__canoe_objects['Application'].Configuration.Modified = False
if os.path.isfile(canoe_cfg):
self.log.info(f'CANoe cfg "{canoe_cfg}" found.')
self.__canoe_objects['Application'].Open(canoe_cfg, auto_save, prompt_user)
self.log.info(f'loaded CANoe config "{canoe_cfg}"')
self.__canoe_objects['Bus'] = win32com.client.Dispatch(self.__canoe_objects['Application'].Bus)
self.__canoe_objects['Configuration'] = win32com.client.Dispatch(self.__canoe_objects['Application'].Configuration)
self.__canoe_objects['Measurement'] = win32com.client.Dispatch(self.__canoe_objects['Application'].Measurement)
self.__canoe_objects['CAPL'] = win32com.client.Dispatch(self.__canoe_objects['Application'].CAPL)
self.__canoe_objects['Measurement'].OnInit += self._IMeasurementEvents_OnInitEventHandler(
self.OnInit)
def __py_canoe_log_initialisation(self, py_canoe_log_dir):
self.log.setLevel(logging.DEBUG)
log_format = logging.Formatter("%(asctime)s [CANOE_LOG] [%(levelname)-5.5s] %(message)s")
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(log_format)
self.log.addHandler(ch)
if py_canoe_log_dir != '' and not os.path.exists(py_canoe_log_dir):
os.makedirs(py_canoe_log_dir, exist_ok=True)
if os.path.exists(py_canoe_log_dir):
fh = handlers.RotatingFileHandler(fr'{py_canoe_log_dir}\py_canoe.log', maxBytes=(1024 * 50), backupCount=20)
fh.setFormatter(log_format)
self.log.addHandler(fh)
def OnInit(self):
self.function = CANoe.CAPLFunction(self.__canoe_objects['CAPL'].GetFunction('function'))
def callFunction(self):
self.function.Call()
if __name__ == '__main__':
canoe_inst = CANoe()
canoe_inst.open(r'file.cfg')
运行后。我收到错误了
AttributeError: '<win32com.gen_py.CANoe 17.2 Type Library.IMeasurement5 instance at 0x1885133501008>' object has no attribute 'OnInit'
我不明白问题出在哪里,因为在官方 COM 文档中我实现了 OnInit 方法,但仍然找不到该属性