Hi,

today we worked quite a bit on making the directory structure more 
C-folks-friendly.
So what we've now done, it we left the general directory structure unchanged, 
but eliminated the maven-like structure.
So now every module has a "CMakeList.txt" file and a "src", "include" and 
"test" directory.
"src" is pretty much what src/main/c and src/main/resources would have been, 
just mixed.
Same applies for "test".

The directory structure now matches that of a lot of other projects and it 
would even allow adding a second set of build configurations to allow building 
PLC4C with MyNewts "newt" build tool (But that's for the future ... no worries)

Today I also added a "simulated" driver which should act similar like the one 
in PLC4J ... in the end it should respect the PLC4C API and be used as some 
dummy driver which mainly helps with writing hello_world applications as well 
as testing new integration modules.

Also did I extend the "system" with a function to manually create and register 
drivers. 

Especially in limited environments like embedded systems, I think the typical: 
"I just add all drivers and load what I need" doesn't work. Same as you can't 
just copy a driver to the device, a dynamic search and discovery mechanism 
would be overkill. We will definitely add similar loading mechanisms like in 
Java, but for now I'll work with manually registering drivers to keep it 
simple, small and efficient.

So far the update for today.

Chris


Am 20.04.20, 16:41 schrieb "Christofer Dutz" <christofer.d...@c-ware.de>:

    Hi all,

    currently we’re in a mode of synchronous exchange on creating the PLC4C API 
on Apache slack “the-asf.slack.com” (Please send an email if you need an 
invite).
    We’re doing that as specially in the beginning this simplifies and speeds 
up things drastically.

    But as we’re at Apache and here “If it didn’t happen on the list, it didn’t 
happen” I’m trying to keep the list in sync with the outcome and give you folks 
the chance to participate by writing up summaries.

    So we have the great situation that Otto and Björn have quite some 
experience in C and C++ and are being a huge help with getting this started.

    So a few weeks ago I have already setup a build that’s integrated into our 
normal Maven build. However you need to enable to profiles in order to do that:

      *   with-sandbox
      *   with-c

    You need to run the maven build at least once as our plc4x-maven-plugin is 
a maven plugin and we need to have it generate some code first (or the build 
will fail)

    The actual build however is done with CMake. This allows us to use any 
CMake-capable IDE to develop PLC4C (I’m using CLion, but VisualStudio seems to 
also work fine).

    Today I created a branch feature/c-api as I think I’ll sometimes be 
committing unbildable stuff in order to allow collaboration (I commit something 
and others fix it ;-) ).
    So please follow this branch.

    Regarding the directory structure, we decided to stick to a structure that 
is sort of aligned with the one we have in PLC4X as this makes it easier to 
understand the structure (at least from a PLC4J point of view). The structure 
should also not be too strange for a c developer. What C developers might 
consider “an abomination” is that I started off using a directory structure for 
modules which is maven-inspired.

    The reason is that I think this allows to cleanly separate prod from test 
code and code from resources (In this case code from header files) … so a C 
module currently has the general structure:

    CMakeLists.txt
    src
    - main
    - c
    - include
    - test
    - c
    - include

    The CMakeLists.txt file is sort of the equivalent to our pom.xml … it tells 
CMake how to build the module. This is also where you define “dependencies” … 
however in C you rather define the locations of the header-files you intend on 
using … the actual using of code will happen by the linker when compiling.

    So now come the parts where I was super happy to have some help with:

      *   In the API module we have a set of header files which define the core 
functions and types
      *   However these types don’t really expose any information on the 
internals of PLC4X. So even if you have a connection structure, you can’t 
access any properties of this directly. If you want to access any properties, 
you need to use the corresponding function. So if in the “connection” domain 
you have a plc4c_connection structure, in order to access the connection_string 
property of that, you need to call the plc4c_connection_get_connection_string 
function and pass in your connection object.
      *   As a currently implicit naming convention we started using a prefix 
“plc4c_” for everything.
      *   We also split up the API functions into domains like “system”, 
“connection”, … all the functions which then results in names like 
“plc4c_system_create”. As we’re expecting the domains to grow, this way we hope 
to keep the sizes of the code blocks manageable.
      *   While the interface a user would use is defined in the API module, 
the implementation is then done in the SPI module (pretty much like in PLC4J)
      *   Initially we started playing around with callbacks, much like we’re 
doing in Java and as C does allow function pointers, that seemed like a good 
idea. But people actually coding in C mentioned that this form of coding feels 
very strange for full-blooded C developers. As we want this API to feel native 
for C developers, we’ll go down this path.
      *   As C doesn’t support a try-catch-finally style error handling, almost 
every function returns a return_code enum which can be translated into error 
messages by using some helper functions. So it is important to check if an 
operation returned OK and to do some error handling, if this is not OK.
      *   The API will completely not use synchronous operations. So we won’t 
provide a blocking “connect” function that returns as soon as the connection is 
established, as some of the systems we’re going to support are single threaded 
and don’t have any mutlitasking or scheduling. Therefore we’ll have a 
“plc4c_system_loop()” function which is cyclically called in order to do 
something.

    So far the update … I hope I didn’t skip anything …

    More will follow :-)

    Chris


Reply via email to