0

I want to save data when close program and load data when it opens. My struct like this

public ref class FormConfig
{
    // Connect form
public: 
    static Int32    Connect_SlaveNo = 0; // + 1 // Axes number                      
    static Int32    Connect_BaudrateNo = 0; 
    static Int32    Connect_PortNo= 0; // port number
    static bool     Connect_DemoCheck = false;  
    static String^  Connect_ConnectInfo = String::Empty;    

};

I try to read/write my static struct data to binary file but didnot get success. I think that to read/write, the static struct need to be convert to byte array. I also used serialization but it can not work with static struct.

I also tried singleton instead of static struct but I have the same problem as this question How to do singleton serialization in C#?.

With Unmanaged C++, everything is very simple like this, but it cannot used in .Net.

struct Medicazos m = {"Bob", "Password", "Feet", 123, 456};

FILE* f = fopen(...);
fwrite(&m, sizeof(struct Medicazos), 1, f);

Can anybody help me ?

2
  • Look at this Commented Mar 14, 2016 at 9:52
  • Thank you for your suggestion. I know that it makes no sense when serialize static struct. But I dont know how to save the static data of struct to binary file :/ Commented Mar 15, 2016 at 0:06

2 Answers 2

2

Well... one way would be not to use static fields in your structure. Why not make a static field that holds a single instance of the struct instead? Or avoid using static in the first place?

In any case, you can always write your own serialization method. It's as simple as this (in C#, since that's what I'm more fluent in and you noted C# as well):

public class MyClass
{
  public static int Field1;
  public static int Field2;

  public static byte[] SerializeStatics()
  {
    using (var ms = new MemoryStream())
    {
      using (var bw = new BinaryWriter(ms))
      {
        bw.Write(Field1);
        bw.Write(Field2);
      }

      return ms.ToArray();
    }
  }
}

The deserialization is the same in reverse - just use a BinaryReader and ReadInt32 for this example.

In addition, some serializers do support static properties, you just usually have to mark them to serialize explicitly. The defaults make perfect sense - you're serializing an instance, what sense does it make to include static class data?

For a stylistic note: Again, it may simply mean you're using static in a way you're used to from some other environment or language, when there's better approaches in C++/CLI or C#. statics tend to be avoided in .NET (and really, many modern programming approaches), the main exception being various examples of caching. The main disadvantage of statics is that it effectively expands the state of every single line of code in your application (and whoever else can reference your application), which in turn is a common source of bugs. You usually want to keep your state as small as possible, relying on parameters and return values instead - it's especially helpful when you start playing around with multi-threading and hosted environments, for example.

Sign up to request clarification or add additional context in comments.

4 Comments

thank you so much for your comment. I serialized the static struct because I want to save that data to a binary file. The manual serialization method may be not good for struct with many types of field. The problem will occur in the deserialization because Binary reader need to know type of field in the struct. Your note about static is very useful. However I wonder that How can use something like Global variable in .Net without static class and singleton?
One of his/her recommendations was to make a single global variable of your struct type, that would then contain instance (non static) fields. Then you should be able to serialize that struct.
@chinhngo Why without a singleton? That's one of the ways of doing what you're trying to do, and it allows you to use serialization just fine. Why have it as a "global variable" anyway? Global variables make your program harder to reason about, generally. It may be fine to have globals (not variables), but that doesn't seem to be your case. You always have some reasonable context where you could have those values, so why not use that? Or maybe use something like dependency injection to handle where the data should be available.
Thank you @ Luaan, I used singleton and the problem was passed.
0

After 2 days, I found the way to save my problem and hope that helps.

A Singleton is used instead of static struct. my code is written in C++/CLI

To save to binary file

#include "stdafx.h"
using namespace System;
using namespace System::IO;
using namespace System::Collections;
using namespace System::Runtime::Serialization::Formatters::Binary;
using namespace System::Runtime::Serialization;



[Serializable]
public ref class Singleton
{   
public:
    String^ str1;
    String^ str2;
    Int32 num;
public:
    // Private constructor allowing this type to construct the singleton.
    Singleton()
    {
        // Do whatever is necessary to initialize the singleton.
        str1 = "2222";
        num =12345;
    }
public:static Singleton^ theInstance ;


public: static property Singleton^ Instance
        { Singleton^ get()
            {
                if (theInstance == nullptr)
                    theInstance = gcnew Singleton();
                return theInstance;
            }
        }
};


int main()
{   
     FileStream^ fs = gcnew FileStream( "C:\\DataFile.dat",FileMode::OpenOrCreate );
    Singleton^ a =  Singleton::Instance;
    Console::WriteLine( "Reason: {0}",a->str1);
    BinaryFormatter^ formatter = gcnew BinaryFormatter; 
    formatter->Serialize(fs, a);
    fs->Close(); 


    return 0;
}

To read from binary file, just change Main()

int main()
{   
         Singleton^ a =  Singleton::Instance;   
    FileStream^ fs1 = gcnew FileStream( "C:\\DataFile.dat",FileMode::Open );    //
    System::IO::FileInfo ^_FileInfo = gcnew System::IO::FileInfo("C:\\DataFile.dat");   
    fs1->Position =0;
    BinaryFormatter^ formatter1 = gcnew BinaryFormatter;
    Singleton^ b = safe_cast<Singleton^>(formatter1->Deserialize(fs1));
    fs1->Close();
    Console::WriteLine( "result: {0}", b->str1 ); 

    return 0;


}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.