I am having an issue with a Siemens WinCC control system that writes C struct data to files on disk under windows.
The C function in the control system (see below) reads the Tag values from the user interface into a struct and then writes it to disk with a call to fwrite and is loaded again from disk using fread.
The problem is that if I enter a value of 55504 to 55511 as the product number (prod_number) in the user interface and then run the below function the struct written to disk is corrupt. The weird thing is that values less than or greater than the above values save to disk and reload fine.
Once inputted into the user interface the prod_number is held in a Tag with the format "Floating-point number 32-bit IEEE 754"
Here is an image of the contents of the struct on disk file showing one that works and one that is corrupt (the lower one is the one that is OK - which has the garbled characters) the top one is missing the needed data because of choking on 55504 as inputted to the user interface.
So I am posting this in the event that someone else has this problem. I'm guessing that there is something wrong with the low level C interface to the disk. I'm not sure, but having experienced this I am now not confident that writing a struct straight to disk is the best way to store and load configuration data.
C-struct and code to write it to disk
#include "apdefap.h" // Define the recipe structure (data elements) - Edit this to fit application needs typedef struct { char name[256], description[256], bar_code[16]; double prod_length, prod_width, prod_height, box_length, box_width, box_height, prod_weight, prod_number; int prod_layers, box_layers, pallet_pattern, pallet_type, prod_rows, prod_columns; int sleeve_req, slip_sheet_req, prod_slipsheet_req, squeeze, stretchwrap, prod_life, boxes_per_layer, box_weight, printing_offset; } RECIPE_DEMO; void raDemo_FileRecipe_Capture(char *Filename) { #ifdef RUN_ON_WEBNAVIGATOR raErrorMsg("raDemo_FileRecipe_Capture", "This is not possible from the WebNavigator client."); #else FILE *f; char filename[1024]; RECIPE_DEMO data; if (MessageBox( NULL, "This will overwrite the recipe file with the current data. Are you sure?", "Capture Recipe", MB_YESNO | MB_ICONEXCLAMATION | MB_SETFOREGROUND|MB_SYSTEMMODAL) != IDYES) return; // Build filename sprintf(filename, "%sRecipes\\%s", raStrRTPath(), Filename); printf ("Recipe: %s\r\n", filename); // Open/create for writing f = fopen(filename,"w"); if (f != NULL) { // Read recipe data from WinCC tags - Edit this to fit your application needs strncpy(data.name, Filename, 255); // Recipe Name/Description strncpy(data.description, GetTagChar("Recipe_Product_Description"), 255); data.prod_length = GetTagDouble("Recipe_Product_Length"); data.prod_number = GetTagDouble("Recipe_Product_Number"); // debug statement printf("Product Number: %lf\r\n", data.prod_number); data.prod_width = GetTagDouble("Recipe_Product_Width"); data.prod_height = GetTagDouble("Recipe_Product_Height"); data.prod_layers = GetTagByte("Recipe_Product_Layers"); data.prod_rows = GetTagByte("Recipe_Product_Rows"); data.prod_columns = GetTagByte("Recipe_Product_Columns"); data.prod_weight = GetTagDouble("Recipe_Product_Weight"); data.box_length = GetTagDouble("Recipe_Box_Length"); data.box_width = GetTagDouble("Recipe_Box_Width"); data.box_height = GetTagDouble("Recipe_Box_Height"); data.box_layers = GetTagByte("Recipe_Box_Layers"); data.pallet_pattern = GetTagByte("Recipe_Pallet_Pattern_Number"); strncpy(data.bar_code, GetTagChar("Recipe_Bar_Code"),16); data.sleeve_req = GetTagBit("Recipe_Sleeve_Req"); data.slip_sheet_req = GetTagBit("Recipe_Slip_Sheet_Req"); data.prod_slipsheet_req = GetTagBit("Recipe_Product_Slipsheet_Req"); data.stretchwrap = GetTagBit("Recipe_Stretchwrap_Req"); data.squeeze = GetTagByte("Recipe_Additional_Squeeze"); data.prod_life = GetTagWord("Recipe_Product_Life"); data.boxes_per_layer = GetTagWord("Recipe_Boxes_Per_Layer"); data.box_weight = GetTagWord("Recipe_Box_Weight"); data.printing_offset = GetTagWord("Recipe_Printing_Offset"); // Write recipe data to the file fwrite(&data,sizeof(data),1,f); // Close the file fclose(f); } else { sprintf(filename, "Error writing to file: '%sRecipes\\%s'\r\nMake sure the destination folder exists.", raStrRTPath(), Filename); raErrorMsg("Capture Recipe", filename); } #endif }
0 Comments
Trackbacks/Pingbacks