Как вызвать общие функции CAPL из Python 3.x?

Проблема

Я пытаюсь вызвать общие функции CAPL (в моем случае timeNowNS), но не знаю, возможно ли это.

общие функции capl

Что я использую?

Я использую Python 3.7 и Vector CANoe 11.0.

Подключение осуществляется с помощью .NET CANoe API. Вот как я принял библиотеки DLL.


import clr
sys.path.append("C:\Program Files\Vector CANoe 11.0\Exec64")  # path to CANoe DLL Files
clr.AddReference('Vector.CANoe.Interop')                      # add reference to .NET DLL file
import CANoe                                                  # import namespace from DLL file

Что я пробовал?

Я успешно открыл симуляцию CANoe, запустил измерение, и у меня есть доступ к сигналам, переменным env и переменным sys.

Затем я создал объект CAPL и попытался использовать метод GetFunction для получения объекта CAPLFunction, чтобы я мог его вызвать.

def begin_can(self, sCfgFile, fPrjInitFunc = None):
     self.open_can()
     self.load_can_configuration(sCfgFile)
     self.start_can_measurement(fPrjInitFunc)

def open_can(self):
    self.mCANoeApp = CANoe.Application()
    self.mCANoeMeasurement = CANoe.Measurement(self.mCANoeApp.Measurement)
    self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
    self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
    self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
    self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
    self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
    self.mCANoeCAPL.Compile()

def getFunction(self):
        function1 = self.mCANoeCAPL.GetFunction('timeNowNS')

        # here I tried also CANoe.CAPLFunction(self.mCANoeCAPL.GetFunction('timeNowNS')) 
        # but i got attribute error: doesn't exist or something like that 

        result = function1.Call()

Ожидаемые результаты

Я должен получить текущее время моделирования с помощью этой функции.

Фактические результаты

Используя приведенный выше код, я получаю:

**COMException**: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
   at CANoe.ICAPL5.GetFunction(String Name)

Я пробовал разные варианты кода, но ничего не добился.

Возможно ли аппаратная проблема? Должен ли я сделать некоторые настройки в моделировании CANoe?

Если вам нужна дополнительная информация, спросите меня! Заранее благодарим

Обновление: я добавил фотографию своей настройки меры после добавления блока CAPL

Настройка измерения


person Stefan Muresan    schedule 16.08.2019    source источник


Ответы (2)


Вы должны написать функцию CAPL, в которой вы вызываете timeNowNS. Затем эту функцию CAPL можно вызвать из Python тем способом, который вы реализовали.

GetFunction работает только с (написанными пользователем) функциями CAPL. Вы не можете напрямую вызывать встроенные функции CAPL (то есть встроенные функции CAPL).

Поместите это в файл CAPL:

int MyFunc()
{
  return timeNowNS();
}

и вызовите вот так из Python:

def getFunction(self):
    function1 = self.mCANoeCAPL.GetFunction('MyFunc')
    result = function1.Call()
person M. Spiller    schedule 19.08.2019
comment
Большое спасибо за ответ, @M. Спиллер! Я добавил свою функцию в файл CAPL, попробовал и получил сообщение об ошибке: **AttributeError: '__ComObject' object has no attribute 'Call'**. И я попытался выполнить приведение к CAPLFunction: function1 = CANoe.CAPLFunction(self.mCANoeCAPL.GetFunction('MyFunc')), но результат Нет. Вы хоть представляете, что пошло не так? - person Stefan Muresan; 19.08.2019
comment
Хм. Во-первых, в гипсе нет необходимости. Некоторые вещи, которые стоит попробовать. 1. возвращаемое значение вашей функции CAPL должно быть int. 2. Функция CAPL должна быть определена в блоке, который является частью настройки измерения CANoe (не настройки моделирования). Это помогает? - person M. Spiller; 19.08.2019
comment
М. Спиллер, возвращаемое значение - int, так что я в порядке, и вы были правы, я объявил функцию в блоке в настройке моделирования, моя ошибка. Я вставил блок в настройку меры и добавил функцию, но все еще не работает, я получаю ту же ошибку: AttributeError: '__ComObject' object has no attribute 'Call'. Я обновил сообщение, добавив в него изображение моей настройки измерения, вам это нравится? Еще раз спасибо! - person Stefan Muresan; 19.08.2019
comment
Выглядит нормально. Можете ли вы получить доступ к другим свойствам объекта CAPLFunction? Например. попробуйте print(function1.ParameterCount). Вы также можете print(function1) убедиться, что был возвращен действительный объект функции. - person M. Spiller; 19.08.2019
comment
Поэтому, если я попробую это сделать без преобразования в CAPLFunction, я получу ту же ошибку: System.__ComObject AttributeError: '__ComObject' object has no attribute 'ParameterCount' Но если я попробую с преобразованием, например: function2 = CANoe.CAPLFunction(mCANoeCAPL.GetFunction('MyTime')) print(function2) print(function2.ParameterCount) result = function2.Call() print(result), я получу следующий результат: System.__ComObject 0 None - person Stefan Muresan; 19.08.2019
comment
Кстати, я нашел кое-что здесь, в главе 2.7, где говорится, что назначение функции CAPL переменной может быть выполнено только в обработчике события OnInit объекта измерения.. Может в этом проблема? - person Stefan Muresan; 19.08.2019
comment
Может быть. Попробуйте сделать следующее в своем коде, а не в обработчике событий: self.mCANoeCAPL.GetFunction('MyFunc').Call() - person M. Spiller; 19.08.2019
comment
Я только что попробовал и получил начальную ошибку в своем сообщении: COMException: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) at CANoe.ICAPL5.GetFunction(String Name). Я не знаю, в чем проблема, но большое спасибо за информацию, я попробую внести некоторые изменения и посмотрю. - person Stefan Muresan; 19.08.2019

После долгого сеанса попыток и ошибок и помощи @ m-spiller я нашел решение.

function2 = None

   def open_can(self):
        self.mCANoeApp = CANoe.Application()
        self.mCANoeMeasurement = self.mCANoeApp.Measurement   # change here: no cast necessary
        self.mCANoeEnv = CANoe.Environment(self.mCANoeApp.Environment)
        self.mCANoeBus = CANoe.Bus(self.mCANoeApp.get_Bus("CAN"))
        self.mCANoeSys = CANoe.System(self.mCANoeApp.System)
        self.mCANoeNamespaces = CANoe.Namespaces(self.mCANoeSys.Namespaces)
        self.mCANoeCAPL = CANoe.CAPL(self.mCANoeApp.CAPL)
        self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)  
        # change here also: explained below

    def OnInit(self):
        global function2
        function2 = CANoe.CAPLFunction(mCANoeCAPL.GetFunction('MyTime')) # cast here is necessary

    def callFunction(self):
        result = function2.Call()

В чем была проблема с исходным кодом?

Проблема заключалась в том, что я пытался назначить функцию переменной после начала измерения.
Как указано здесь, в главе 2.7, назначение функции CAPL переменной может быть выполнено только в обработчике события OnInit Объект измерения.

Я добавил эту строку, изучая документацию:

self.mCANoeMeasurement.OnInit += CANoe._IMeasurementEvents_OnInitEventHandler(self.OnInit)

После его добавления при инициализации была выполнена функция OnInit, а функция CAPL была назначена переменной, и впоследствии я мог использовать эту переменную для вызова функции.

Еще раз спасибо, @ m-spiller!

person Stefan Muresan    schedule 20.08.2019