Как определить размер структуры ?C#

563
01 января 2017, 17:16

Всем доброго времени суток помогите пожалуйста определить размер структуры в C#, есть некая структура на C++ :

typedef struct {
short int n;                        
unsigned long adr;                  
int nz,ms;                          
TDateTime tr;                       
TDateTime tz;                       
TDateTime tv;                       
TDateTime ts;                       
short tm,sk,dop;                    
float bz,hz,hzz,hdm,hdp,h0,h1;      
float l,ldm,ldp,lbm,lbp;            
float pf,pt,pdm,pdp,pbm,pbp,pu,pe;  
float l_1,l_2,l_3,l_4;              
float h1s,h2s,h3s,h4si,h1si;        
float t1s,t2s,t3s,t4s;              
float d1,d2,d3,d4;                  
float gh4n,gh4z,gh4s,gh1z,gh1s;     
float l4;                           
float d_rr,d_rv;                    
int k_t,k_z;                        
float f_rez[4];                     
int i_rez[4];                       
} ser;  

И еще одна :

typedef struct {
TDateTime dt;            
short int Nbr,Nsm,Nr;    
float pt,pf,pdm,pdp;     
float pbm,pbp,pu,pe;     
float ps[12];            
float ph[8];             
float phu[8];            
//int prs,pr[8];         
int prs;                 
short pr[8],kr[8];       
unsigned int m[16];      
unsigned int s[16];      
float frez[4];           
int irez[4];             
} str_sm;               

Далее в С++ идет определение размеров этих структур :

fser=CreateFile(AnsiString(S).c_str(),GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
 if (fser!=INVALID_HANDLE_VALUE)
    {
    long int ss=sizeof(str_sm)+((nrs.n.nr-1)*(sizeof(ser)));
    SetFilePointer(fser,ss,NULL,FILE_BEGIN);
    ReadFile(fser,&sr,sizeof(ser),&lread,NULL);
    CloseHandle(fser);
    flag=true;
    }

Как мне тоже узнать размер структуры ? что бы произвести сдвиг в бинарном файле, пробую так :

struct test
        {
            int n;                      
            ulong adr;                  
            int nz, ms;                      
            double tr;                       
            double tz;                       
            double tv;                       
            double ts;                       
            short tm, sk, dop;                    
            float bz, hz, hzz, hdm, hdp, h0, h1;    
            float l, ldm, ldp, lbm, lbp;            
            float pf, pt, pdm, pdp, pbm, pbp, pu, pe;
            float l_1, l_2, l_3, l_4;          
            float h1s, h2s, h3s, h4si, h1si;   
            float t1s, t2s, t3s, t4s;          
            float d1, d2, d3, d4;              
            float gh4n, gh4z, gh4s, gh1z, gh1s;
            float l4;                          
            float d_rr, d_rv;                  
            int k_t, k_z;                      
            float[] f_redz1;                   
            float[] f_redz2;                   
            float[] f_redz3;                   
            float[] f_redz4;                   
            float[] f_redz5;                   
            int[] i_rez1;                      
            int[] i_rez2;                      
            int[] i_rez3;                      
            int[] i_rez4;                      
            int[] i_rez5;                      
        }
test te = new test();
            int abcd = System.Runtime.InteropServices.Marshal.SizeOf(typeof(test));

на выходе я получаю 296 ... Я проделал то же и со второй структурой и при таком решении abcd + 0 * abcd2 = 296 (Но я запустил отладчик на С++ и там число = 360). Помогите пожалуйста разобраться, большое спасибо.

Answer 1

Извините, что пишу в ответе, но Вы уверены, что размер структуры ser в вашем проекте именно 360. Сейчас определил эту структуру в C++ Builder 6. Её sizeof равен 280. Также проверил в MSVC, заменив TDataTime на double, там тоже 280.

На C# выровнял структуру так, чтобы её размер равнялся 280 байт. У вас были проблемы с выравниванием структуры, и Вы не совсем правильно массив перевели в C#-структуру.

В итоге Ваша структура выглядит так:

[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct test
{
    int n;
    ulong adr;
    int nz, ms;
    double tr;
    double tz;
    double tv;
    double ts;
    short tm, sk, dop;
    float bz, hz, hzz, hdm, hdp, h0, h1;
    float l, ldm, ldp, lbm, lbp;
    float pf, pt, pdm, pdp, pbm, pbp, pu, pe;
    float l_1, l_2, l_3, l_4;
    float h1s, h2s, h3s, h4si, h1si;
    float t1s, t2s, t3s, t4s;
    float d1, d2, d3, d4;
    float gh4n, gh4z, gh4s, gh1z, gh1s;
    float l4;
    float d_rr, d_rv;
    int k_t, k_z;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    float[] f_redz;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    int[] i_rez;
}

Проверьте ещё раз совместимость C#-структуры при чтении бинарных файлов. Ещё я импортировал пространство имён для кода C#:

using System.Runtime.InteropServices;

Обновлено: Или вы говорили про вторую структуру. Её размер как раз 360. И на C# выглядит она так:

[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct str_sm {
    double dt;
    int Nbr, Nsm, Nr;
    float pt, pf, pdm, pdp;
    float pbm, pbp, pu, pe;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
    float[] ps;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    float[] ph;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    float[] phu;
    int prs;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    short[] pr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    short[] kr;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    uint[] m;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    uint[] s;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    float[] frez;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    int[] irez;
READ ALSO
“Не удалось загрузить файл или сборку” VkNet.dll

“Не удалось загрузить файл или сборку” VkNet.dll

Необработанное исключение типа "SystemIO

717
Проблема с установкой Visual Studio 2015

Проблема с установкой Visual Studio 2015

При установке произошел сбой с ошибкой

401
“Значение не может быть неопределенным”

“Значение не может быть неопределенным”

При попытке получить картинки пользователя, получаю: Значение не может быть неопределенным

375