Makers Blog

Userdefined Array in Native Function Block and some questions about it

liqunzhao 17 November 2023 min. read
1,477 views 1 comments

Demo description

  • The following example uses the Native Function Block to create a user-defined Array interface with PLCncli toolchain
  • The Array consists of 21 elements, each of which is a structure. The structure contains two IecString80, and an enumeration, as shown in the following diagram.


  • Make sure that the ToolChain version is 23.0 or higher. This example uses the 23.6 ToolChain for demonstration purposes.
  • Familiar with the basic process of establishing a Native Function Block.
  • Visual Studio 2019 or 2022 with ToolChain add-in plugins
$ plcncli  --version

plcncli (


  • Create a new project using Visual Studio, select "Shared Native Function Block" project type, and name the project "ArrayTest."
  • Then, within the ArrayTest project in Visual Studio, create a new Native Function Block named "ArrayCplus."


  • Copy those code to ArrayCplus.cs

  • Because there are some display issues when directly including the source code here, such as & and >, I provided a link instead.

  • for example, the & will be encode as & in this html.....



Open the terminal in the ArrayTestCpp folder and enter the following.

$ plcncli generate code

After generating the code, locate the ArrayTest-cli32.h and ArrayTest-cli64.h files in the src directory, and find the places where #error is indicated.


We need to remove the comments and improve the code. Click to navigate to InArrayFB-cli.cpp and modify the implementation.



In ArrayCplus.cpp, enter the following code. Contents containing strings must be initialized in the process rather than in the Init region; initializing them in the Init region will not work, resulting in the inability to write values to sName and sAttribute through Engineer.



Open the terminal in the ArrayTestCpp folder and enter the following.

$ plcncli build all
$ plcncli deploy


Open the PLCnext Engineer and load the ArrayTest.pcwlx add an variable to the ArrayTest named arr

Now it can work



  • Although this method works in practice, why is it necessary to initialize content containing IecString or User-defined String in the void PInvoke ArrayTest::ArrayCplus::Process() instead of in the void PInvoke ArrayTest::ArrayCplus::Init()? it doesn't work if i put the code in the void PInvoke ArrayTest::ArrayCplus::Init().
  • It's clear that there is no corresponding tutorial on userdefine arrays for Native Function Blocks on GitHub. Can somebody supplement and improve it? (the way that Csharp Userdefine array is not work in the native function block)
  • One last point that also confuses me is why, regardless of whether it's IecString, User-defined String, or IecStringEx*, if they contain strings, they must be in the form of 【InOut】in CSharp code when used as a Native Function Block?


The Makers Blog shows applications and user stories of community members that are not tested or reviewed by Phoenix Contact. Use them at your own risk.


Please login/register to comment


Leave a Reply

liqunzhao 30.11.2023

After communicating with Martin Boers, the first question has been answered. By building an Init() function in Structure and Array in CSharp, it can be implemented in C++ to achieve initialization effects. As for the third question, after applying the method from the first question, interfaces containing String can now be specified as [Input] instead of [InOut], and I have updated the corresponding code repository. Nice ~

Login / Register to reply
Never miss a new article
Sign up for the newsletter
Never miss news about PLCnext Technology
Get interesting content via newsletter four times a year
Receive exclusive information before all other users