0

While my specific situation is dealing with a third party library, which I am referring to in my example, I think the question is applicable to a much wider audience as at the heart of it, it is about dynamic structure creation.

Background:

I am currently writing an automation application that uses a third party library to communicate with Programmable Logic Controller's (PLC's). When reading a user defined data type from the PLC (which is like a vb.net structure but with only values in it, no methods or properties etc.), the third party library will read the data from the PLC as a block, no matter if it is a single variable or an array. Then I need to provide a vb.net data type as a matching structure to the one in the PLC to map the read block of data to the appropriate structure members in my program.

Example:

In the PLC I have a data type which contains two 32bit numbers, one called IndexCount and one called Zone. To read one tag, or variable, of that data type I need to specify a matching data type in vb.net (the names don't have to match, but the data types must)

Private Structure RecordUDT
    Dim IndexCount As Int32
    Dim Zone As Int32
End Structure

I then read the data by declaring a variable of my own structure and using an encoder, which is provided by the third party package. (The PLC data has been read into 'plcData' in a previous line in the actual application)

dim myData as RecordUDT
myData = thirdPartyEncoder.ToType(plcData, 0, GetType(RecordUDT)) 'Convert the data in 'plcData' to a RecordUDT type

I can now look at myData.Zone and it will have the same value as the .zone member in the PLC.

The question:

The third party encoder requires me to provide the data type, RecordUDT in this example, as in the line below:

myData = thirdPartyEncoder.ToType(plcDataBlock, 0, GetType(RecordUDT)) 'Convert the data in 'plcData' 

The only way I know how to define a structure is as in the Background above. The downside of this is that the PLC's can have any number of their own structures that I or other users want to read, and that means that I have to make a new version of the software, with the structure hard coded in it, each time they want to read a new one. The program itself would be the same except for the Structure definition and the line above, which would provide the name of the new structure.

Is there a way to make dynamic structures so that they can be created at runtime, or by entering the information in a file that is read at start-up (or something similar)?

If not, is there another way to solve this problem without having to distribute a new version of the application each time a new structure needs to be added?

What I have done so far:

A lot of reading and not getting anywhere, as I am getting stuck at square one, the structure creation... I have searched on Google and here on SO for things like:

"vb.net create structures at runtime" and "vb.net create struct at runtime"

"vb.net dynamic structure"

".net dynamic structure"

".net create structure at runtime"

I found this article which showed some promise, but it is in C and over my C skills, and I don't know if there is a similar system that can be made within the confines of .NET's managed design. This answer also has similarities, but doesn't address the dynamic creation of the structure. Most other results that are similar refers to databases and the answers have always been to use database procedures instead of dynamic structures, which doesn't help me either (as far as I can tell anyway).

I got my hopes up by the following thread, dynamically-create-structure, but the two main links referred to in the answer were 404, not found :-(

From what I have read, it doesn't seem to be something that is done, based on lack of information and comments like "if you create the structure dynamically, how are you going to reference it" etc. A lot of it hints that it is not possible or wise, but I very much doubt that I am the only one in this situation where a new version of a software would be needed each time a user needs a new structure, which could be very often.

I would appreciate if someone can point me in the right direction. I also realize that the right direction might be entirely different to the way I am heading, but I don't mind turning around :-)

Community
  • 1
  • 1
Pingu
  • 1
  • 2
  • I've worked with APIs in the past where I had the data in a byte array in memory, and needed it loaded into a struct. It's been a long time, but I think I used the `System.Runtime.InteropServices.Marshal` class, specifically `Marshal.PtrToStructure`. Have you looked at using that or any of the other methods on that class? – pmcoltrane May 27 '14 at 23:49
  • Thanks for your reply @pmcoltrane. I haven't looked down that avenue. Would I be correct in thinking that it might be what they use internally in their API? If I was able to use that, would I then do the conversion from a byte array myself and not use the supplied "ToType" method? I'll have a look in the manuals for Marshal.PtrToStructure right away :-) – Pingu May 27 '14 at 23:58
  • All I can tell you is that your problem sounds similar to mine. My application interfaced with a CNC device, not a PLC, but its API returned data in the form of a byte array containing multiple structs. I had to iterate through the array, reading a header to determine type and length, and then use `Marshal` to wrangle the bytes into the appropriate type of struct. I no longer have the source code, but I think that's the way I handled it. – pmcoltrane May 28 '14 at 00:12
  • It sounds similar indeed. I had a look at the classes you mentioned and in the examples I found they are all using a pre-defined structure in their PtrToStructure, which is my issue. I can see where you are coming from with the iteration and trying to determine each part of the data. I think I will wait and see if there are other possible ways before heading down the byte-wrangling track ;-) – Pingu May 28 '14 at 00:28

1 Answers1

0

When I was looking into deeper topics in Java, I ran into a few similar situations. My searching was largely unfruitful until I tripped onto what the concept is called - Generic Types. Scripts that are written to hold and accept data from many different types. Then, worst case when an interface changes, you just need to update the reader to pass the library what it's expecting, but will return a list of generic objects that you can process later once their type is determined, keys identified and then they can be processed. Start here with MSDN. I hope that helps.

Jaaz Cole
  • 3,119
  • 1
  • 15
  • 20
  • Thanks for your answer. As soon as the site opened I recognized the image of the screwdrivers and realized I have tried to solve this before (short memory span ;-) The issue I had is summarized in the analogy they have: "...a screwdriver set with removable heads. You inspect the screw you need to turn and select the correct head for that screw ..." They way I see it, I still need to define the "head" which is where the dynamic structures come in. It might be my lack of programming skills that prevents me seeing how to use Generics properly though. – Pingu May 28 '14 at 00:46