你能给我一个例子,说明如何在我的库中声明一个指向函数的指针?如何将指向函数的指针传递给外部库?
答案 0 :(得分:0)
TL; DR:在CoDeSys v3中可能会带来手提包,并且变得非常简单。
在CoDeSys中,“功能”实际上是存储在功能表中的功能指针。
在CodeSys v2中,要获取必须使用INDEXOF(F_MyFunction)
的函数的地址,这将在函数表中提供函数指针的索引。嗯,获取表格的地址对读者来说是一个练习(可以通过一些体操运动来取回)。
在CoDeSys v3中,ADR
代替了INDEXOF
,因此ADR(F_MyFunction)
为您提供了指向F_MyFunction
的代码的函数指针的地址!>
猜猜是什么:您可以设置该函数指针,而F_MyFunction(...)
只是通过该函数指针的调用。
就这么简单。
因此,要进行间接函数调用,您需要做的就是声明一个虚拟的“函数”,实际上它就像可设置的函数指针一样工作!
假设我们有两个目标函数要间接调用:
FUNCTION F_Add1: INT
VAR_INPUT
param : INT;
END_VAR
F_Add1:= param + 1;
END_FUNCTION
FUNCTION F_Add2: INT
VAR_INPUT
param : INT;
END_VAR
F_Add2:= param + 2;
END_FUNCTION
然后,我们定义一个“函数指针”,该函数必须具有与间接调用的函数相同的签名:
FUNCTION FPTR_Add : INT
VAR_INPUT
param : INT;
END_VAR
END_FUNCTION
我们还可以有一个分配给函数指针的助手:
F_FPTR_Assign
VAR_INPUT
dst : POINTER TO PVOID;
src : POINTER TO PVOID;
END_VAR
dst^ := src^;
END_FUNCTION
最后,让我们进行一些间接调用:
// should return 3 if indirect calls work
FUNCTION F_Test : INT
VAR
val : INT;
END_VAR
F_FPTR_Assign(ADR(FPTR_Add), ADR(F_Add1));
// FPTR_Add points to F_Add1
val := FPTR_Add(val);
// here val has value 1
F_FPTR_Assign(ADR(FPTR_Add), ADR(F_Add2));
// FPTR_Add points to F_Add2
val := FPTR_Add(val);
// here val has value 3
F_Test := val;
END_FUNCTION
此方法的唯一缺点是,调试器不会检查函数指针的动态值,因此 stepping 的行为类似于 step over 。解决方法是在目标函数中设置断点,然后进入和进入都将在此处停止。
还有其他方法可以达到这种效果,例如通过直接操作堆栈帧,因此即使由于CoDeSys的某些更改而使此精确方法无法正常工作,也有其他方法可以实现。
答案 1 :(得分:-1)
在codesys
中可以使用指针。要在codesys
中创建指针,您可以
VAR
pVar : POINTER TO BYTE;
tempVar : BYTE;
derefereceVar : BYTE;
END_VAR
//get a pointer to the byte variable
pVar := ADR(tempVar);
取消引用你想要的指针
derefereceVar := tempVar^;
因此,如果您希望将指针作为函数的参数,则可以将上面示例中的pVar
或ADR(tempVar)
传递给函数的参数POINTER_TO_BYTE
作为类型。
答案 2 :(得分:-1)
在基于Codesys的平台中,可以创建指向数据类型或功能块的指针。在TwinCAT 3中,也可以创建一个函数指针,但不能在PLC程序中调用它。函数指针只能作为外部库组件的参数给出。