如何在codesys v3中创建指向函数的指针

如何在codesys v3中创建指向函数的指针,c,codesys,iec61131-3,C,Codesys,Iec61131 3,你能给我一个例子,说明如何在我的库中声明函数的指针吗?如何将指向函数的指针传递到外部库?在codesys中可以使用指针。要在codesys中创建指针,您可以 VAR pVar : POINTER TO BYTE; tempVar : BYTE; derefereceVar : BYTE; END_VAR //get a pointer to the byte variable pVar := ADR(tempVar); 要取消对该指针的引用,您需要 derefereceVar

你能给我一个例子,说明如何在我的库中声明函数的指针吗?如何将指向函数的指针传递到外部库?

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)
传递给函数的参数,该参数的类型为
指向字节的指针。

编辑09/2020:请参阅本主题中的另一个答案,忘掉这一个

在基于Codesys的平台中,可以创建指向数据类型或功能块的指针。在TwinCAT 3中,也可以创建函数指针,但不能在PLC程序中调用。函数指针只能作为外部库组件的参数提供

选中此项:
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
此方法的唯一缺点是调试器不检查函数指针的动态值,因此单步执行的行为类似于单步执行。解决方法是在目标函数中设置断点,然后单步执行和单步执行都将在此处停止


还有其他方法可以达到这种效果,例如,通过直接操纵堆栈帧,因此,即使这种精确的方法由于CoDeSys中的某些更改而停止工作,也有其他方法可以达到这种效果。

感谢您的回复,但我喜欢创建指向函数的指针,例如在c语言中,我们这样做:int sum(int num1,int num2){return sum1+sum2;}int main(){int(*f2p)(int,int);f2p=sum;int op1=f2p(10,13);int op2=sum(10,13);printf(“输出1–通过指针调用函数:%d”,op1);printf(“输出2–直接调用函数:%d”,op2);返回0;}所以我也喜欢在codesys中做同样的事情,将这个指针发送到我的外部图书馆。我刚刚注意到我收到了一些反对票。只是想知道回答这个问题是否有什么问题。你不能在codesys 3的PLC代码中做函数指针。但是你可以,ADR是你如何做的-ADR的文档中没有任何关于这个问题的内容你链接到的与此相反。他们不记录ADR产生的结果,即如何使用它。这取决于你自己的努力,但很容易理解。你在32位或64位内核模式下运行,内存平坦,可以说世界是完全开放的。对内存内容的调查根本没有什么大不了的。感谢你对这个问题的回答pic,太鼓舞人心了!非常感谢。这在Beckhoff的TwinCat3中也发挥了完美的作用!@dotKokott您可能想联系您的Beckhoff代表,告诉他们,在当今时代,对此类体操的需求是不可接受的。函数指针或等价物是任何现代编程系统的基本功能,而事实上,TC3是没有官方支持他们就像是在脸上打了一记耳光。软件工程界需要对像CoDeSys和Beckhoff这样的供应商施加强大的压力,他们的开发工具都停留在上个世纪的下半叶。如果他们听到的只是板球,他们不会有任何改进。我们需要改变。请联系他们。我是个人y参与了大规模迁移Beckhoff TC3 PLC运行时,正是因为他们的开发系统非常糟糕,而且在任何可以想象的方面都非常落后,这是对一个人智力的侮辱。任何软件开发都要求源代码与git兼容,并且工具易于自动化。他们提供了一些ip服务,但这确实是一个巨大的谎言,与任何其他现代开发工具相比都是完全落后的。CoDeSys和TC3都用随机垃圾污染源文件夹,这是第一个大禁忌。这只是一个下坡路