2016-05-29 2 views
0

Я переводил игру C: https://github.com/minirop/Super-Mario-Remake в C# для удовольствия и для улучшения моего программирования на C#. Я не настолько разбираюсь в программировании на C и наткнулся на структуру, которую я не знаю, как реализовать на C#.Перевод этой C-структуры на C#

typedef struct _state_t { 
    void (*init)(struct _state_t * s); 
    void (*update)(struct _state_t * s, Uint32 elapsedTime); 
    void (*handleEvent)(struct _state_t * s); 
    void (*draw)(struct _state_t * s, SDL_Surface * surface); 
    void (*clean)(struct _state_t * s); 
    void * data; 
} state_t; 

Что я пытался до сих пор:

public class state_t 
{ 
    public void init(state_t S) 
    { 
     state_t s; 

     s = S; 
    } 

    public void update(state_t S, UInt32 ElapsedTime) 
    { 
     state_t s; 
     UInt32 elapsedTime; 

     s = S; 
     elapsedTime = ElapsedTime; 
    } 

    public void handleEvent(state_t S) 
    { 
     state_t s; 
     s = S; 
    } 

    public void draw(state_t S, SDL.SDL_Surface Surface) 
    { 
     state_t s; 
     SDL.SDL_Surface surface; 

     s = S; 
     surface = Surface; 
    } 
    public void clean(state_t S) 
    { 
     state_t s; 

     s = S; 
    } 

    public void data() 
    { 

    } 
} 

Но я не думаю, что это правильно. Я получил сообщение об ошибке:

 state_t MS_get() 
     { 
      state_t state = new state_t(); 
      state.init = MS_init; // Error 2 Cannot assign to 'init' because it is a 'method group' 

     } ... 
+0

My C ржавеет, но он выглядит как указатель на функцию. Поэтому 'init' должен переводить на что-то вроде' public Action <_state_t> init; '. Тем не менее, если вы попробуете преобразование 1: 1, вы быстро столкнетесь с ограничениями на C#. Лучше попытаться понять код, а затем переписать его с помощью подхода ООП. –

+0

Хорошо, спасибо. Я попробую это. Да, это также мое намерение переписать это на ООП. Я вообще не опытный программист, поэтому я пробовал и пробовал много. – Runebjornb

+0

Это грубый эквивалент интерфейса. Все члены - это данные, а не код. Указатели функций. Вы пишете эквивалентную структуру с членами делегата. Сначала вам нужно объявить типы делегатов, для изменения CallingConvention в Cdecl потребуется атрибут [UnmanagedFunctionPointer]. Если вы должны инициализировать структуру вместо ее использования, тогда инициализируйте объекты-делегаты-члены для нацеливания метода в вашем коде. Не забудьте сохранить его в * статической * переменной, чтобы сборщик мусора не избавился от него. Много способов проиграть, проще сделать в C++/CLI. –

ответ

0

Вы определили init как метод, поэтому вам нужно вызвать его; не назначать его. Нечто подобное должно работать:

state.init(MS_init);

Однако, я вижу в этом методе вы просто спасительной состояния в переменной, объявленной внутри метода init(), это ничего не добьешься.

+0

Да, я не закончил программирование методов. Это был прямой перевод с C-структуры на C#, что я считал правильным. Это проблема не для понимания этой C-структуры. – Runebjornb

0

Эта структура C состоит из объектно-ориентированного класса C++ или C#. Объектно-ориентированные принципы принудительно вставляются в эту структуру.

Эквивалент C# структура будет

public class state_t 
{ 
    Unit32 m_elapsedTime; 
    SDL_Surface * m_surface; 
    void *m_data; 

    public void init() 
    { 
     // Initialise all variables of class 
    } 

    public void update(UInt32 ElapsedTime) 
    { 
     m_elapsedTime = ElapsedTime; 
    } 

    public void handleEvent() 
    { 
     // Code for Handle Event 
    } 

    public void draw(SDL_Surface Surface) 
    { 
     // Code for Draw 
     m_surface = Surface; // maybe, need to check datatype. 
    } 
    public void clean() 
    { 
     // Code for Cleaning 
    } 

    public void data() 
    { 
     // Code for filling *data variable 
    } 
} 

Вы можете добавить еще несколько приватных переменных, особенно в отношении размеров распределения памяти в m_data и m_surface, но это будет зависеть от дальнейшего изучения оригинала код.

+0

Нет ли другого способа, кроме как использовать указатели в моем случае? – Runebjornb

+0

Какие указатели вы имеете в виду здесь? –

+0

Эти: SDL_Surface * m_surface; void * m_data; – Runebjornb