@Ultrakayo

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

C++言語で作成した構造体をC#に移植したい

C++
struct SYSINFO {
unsigned short id;
unsigned short cnt;
unsigned short disp;
unsigned short cf;
unsigned short rsv1[4];
unsigned short no[4];
unsigned char sel[4];
unsigned char type[4];
}
main.h
class TSample: public TForm
{
public: SYSINFO sysinfo[64];
main.cpp
TSample *sample;

art.cpp
sample->sysinf[10].id=0x890;
sample->sysinf[10].sel[5]=4;
みたい 使い方します。
 C# でも 同じような方法が できないでしょうか?

例 
work.cs
public class SysInfoClass{
public UInt16 id;
public UInt16 cnt;
public UInt16 disp;
public UInt16 cf;
public UInt16[] rsv1 = new UInt16[4];
public UInt16[] no =new UInt16[4];
public Byte[] sel= new Byte[4]
public Byte[] type=new Byte[4];
}

main.cs
public static SysInfoClass[] sinfo = new SysInfoClass[64];

sinfo[0].id = 0x980;
sinfo[0].rsv1[0] = 1; <<<< ここで 実行エラー

いろいろ 試しましたが
 うまくいきません。
ご教示願います。
※ 一次配列なら うまく動作しますが
  二次配列は どうも コンパイルOKでも
  DEBUGで エラー 
追補:
work.cs
最初から 二次配列にすれば問題ないようですが
public class SysInfoClass{
public UInt16[] id =new UInt16[64];
public UInt16[] cnt=new UInt16[64];
public UInt16[] disp=new UInt16[64];
public UInt16[] cf =new UInt16[64];
public UInt16[,] rsv1 = new UInt16[64,4];
public UInt16[,] no =new UInt16[64,4];
public Byte[,] sel= new Byte[64,4]
public Byte[.] type=new Byte[64,4];
}
この場合
 syinfo.id[0]=0x980;
 syinfo.rev1[0]=1;
のようになってしまいます

sinfo[0].id = 0x980;
sinfo[0].rsv1[0]=1;
プログラムの都合上
sinfo[0].id = 0x980;
sinfo[0].rsv1[0]=1;
 こういう使い方をしたいのです
 

0 likes

3Answer

public static SysInfoClass[] sinfo = new SysInfoClass[64];
sinfo[0].id = 0x980;
sinfo[0].rsv1[0] = 1; <<<< ここで 実行エラー

エラーが出ているのはそこではなく sinfo[0].id = 0x980; の時点です。 new SysInfoClass[64] で作った配列はすべての要素が null になるため、 sinfo[0].id = 0x980; は配列0番目の null に対して id フィールドに代入しようとしてエラーになります。

以下のように配列を初期化してください。

public static SysInfoClass[] sinfo = new SysInfoClass[64];
for (int i = 0; i < sinfo.Length; i++)
{
    sinfo[i] = new SysInfoClass();
}

なお追補についてですが、そこを二次元配列にしても元々のエラーが解消することはないはずです。何か勘違いしているのでは。

0Like

Comments

  1. @Ultrakayo

    Questioner

    Program.cs
     実際は  var chinfo = new ChargeInfo[4];
    for(int i=0;i<4;i++)
    chinfo[i] = new ChargeInfo();
    chinfo[0].id=0x0430;
     配列サイズは4で このProgram.cs内では
     良いのですが、他の xxxx.csでchinfo[0].id=0x0430;を
     使いたい 所謂 グローバル変数的な 使い方をしたわけです   
      
     

  2. 何が言いたいかよく分かりません。元の質問と全然違うコードのようですが。

    また Program.cs に var chinfo = new ChargeInfo[4]; と書いても chinfo は他のファイルから参照できないので、それが実際のコードというのも謎です。動いているコードがあるなら改変せずに貼ってください。

  3. @Ultrakayo

    Questioner

    色々 試行錯誤してたら 元のファイルが無くなり ダメなファイルですが
    public class ChargeInfo
    {
    public UInt16 id;
    public Byte enable;
    public static Byte[] chk = new Byte[4];
    public static Byte[] StartTimeH = new byte[4];
    public static Byte[] StartTimeM = new byte[4];
    public static Byte[] EndTimeH = new byte[4];
    public static Byte[] EndTimeM = new byte[4];
    public static UInt16[] Time = new UInt16[4];
    public static UInt16[] charge = new UInt16[4];
    public readonly static ChargeInfo[] SharedArray = new ChargeInfo[4];
    public static ChargeInfo[] CreateSharedArray()
    {
    var chinfo = new ChargeInfo[4];
    for (UInt16 i = 0; i < chinfo.Length; i++)
    chinfo[i]=new ChargeInfo();
    return chinfo;
    }
    }
    main,cs
    var chinfo = new ChargeInfo[4];
    for(int i=0;i<4;i++)
    chinfo[i] = new ChargeInfo();

      chinfo[0].chk[0] = 1; //これは ダメ
     二次配列の初期化が 抜けていると

  4. @Ultrakayo

    Questioner

    追補:
    public class MaxChargeInfo
    {

            public UInt16 id;
            public UInt16 day_cnt;
    

      public UInt16 entry_cnt;
    public UInt16 time_cnt;
    public Byte[] DayChk = new Byte[4];
    public UInt16[] DayCharge = new UInt16[4];
    public Byte[,] Entry = new Byte[4,4];
    public UInt16[,] Entrycharge = new UInt16[4,4];
    public UInt16[,] EntrySs = new UInt16[4, 4];
      public Byte[,] timeChk = new Byte[4, 4];
    public Byte[,] StartTimeH = new Byte[4,4];
    public Byte[,] StartTimeM = new Byte[4, 4];
    public Byte[,] EndTimeH = new Byte[4, 4];
    public Byte[,] EndTimeM = new Byte[4, 4];
    public UInt16[,] TimeCharge = new UInt16[4, 4];
    };
    program.cs
    internal static class Program
    {
    public static MaxChargeInfo[] maxchinfo = new MaxChargeInfo[4];
    public static void Main()
    {
    for(int j=0;j<4;j++)
    maxchinfo[j] = new MaxChargeInfo();
    maxchinfo[0].DayChk[0] = 0;
    これなら コンパイルは通るのですが 

  5. @Ultrakayo

    Questioner

    他の人から 
    public struct INFO
    {
    public UInt16 id;
    public UInt16 No;
    public Byte error;
    public Byte rsv1;

    public readonly static INFO[] SharedArray = CreateSharedArray();
    
    private static INFO[] CreateSharedArray()
    {
        var infos = new INFO[64];
        for (UInt16 i = 0; i < infos.Length; i++)
        {
            infos[i].id = 0xfe04;
            infos[i].No = i;
        }
        return infos;
    }
    

    }
    こういう風にすれば どこからでも アクセスできますよと
    しかし  構造体には 二次元配列が 含まれていなかったので
    いろいろ作り変えたのが 最初の文です。  

  6. 「色々 試行錯誤してたら 元のファイルが無くなり ダメなファイルですが」のコメントについてですが、

    chinfo[0].chk[0] = 1; //これは ダメ
    二次配列の初期化が 抜けていると

    これでエラーが出るのは二次元配列の初期化が抜けているのではなくて(そもそもそのコードの中に二次元配列は出てきません) static である chk フィールドに代入しようとしているからです。

    その次、「追補」のコメントについてですが、コンパイルが通るなら何が問題なのですか?コードがまた大きく変わっていて前の質問とのつながりが分からず、コードで何が達成したいのかも読み取れないので、特にアドバイスできません。

    その次のコメントについてですが、

    こういう風にすれば どこからでも アクセスできますよと
    しかし  構造体には 二次元配列が 含まれていなかったので
    いろいろ作り変えたのが 最初の文です。

    前のコメントでも何度か二次元配列の話が出てきていましたが、移植元の C++ の構造体に二次元配列が含まれていないのに、 C# で二次元配列を使おうとしているのはなぜですか?

  7. 話をするたびに出てくるコードや起きている問題が変わると回答する側としても困るので、やりたいことを明確にし、実際のコードを確定してから質問し直してください。

This answer has been deleted for violation of our Terms of Service.

そもそもC#上で固定長配列を持つ構造体を扱うのは面倒なので、C#でやるならクラスやList等を使ったり、C#のやり方でコーディングした方がいいです。
無理矢理C++的な事をするなら、最初からC++で組んだ方がよいと思います。

0Like

Your answer might help someone💌