Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Темы - Jordan

Страницы: [1]
1
Общий раздел / Закат солнца вручную!
« : Февраль 22, 2019, 03:24:33 pm »
Приветствую!

Решил написать минимальное приложение на winapi.

Стал реализовывать работу с памятью через winapi.

Программа падает.

Как компилю.(использую mingw)
"..\..\mingw\bin\g++" -omain -s -nostdlib -fno-rtti -fno-exceptions -fno-use-cxa-atexit -Wall -Wformat -Werror main.cpp -lkernel32 -luser32

сам исходник

#include <windows.h>

class Memory
{
private:
  HANDLE Heap;

public:
Memory()
{
  Heap = HeapCreate(0,0x01000,0);
}

void * Allocate(unsigned int Size)
{
  return HeapAlloc(Heap, 0, Size);
}

void Deallocate(void * Src)
{
  HeapFree(Heap, 0, Src);
}

~Memory()
{
  HeapDestroy(Heap);
}

};

static Memory GlobalMemoryAllocator;

void * operator new(unsigned int Size)
{
  return GlobalMemoryAllocator.Allocate(Size);
}

void operator delete(void * Src)
{
  GlobalMemoryAllocator.Deallocate(Src);
}

class Mem
{
public:
  int m_Data;
};

void Main()
{

Mem * p = new Mem;

        p->m_Data = 5;

        if (p->m_Data > 10)
        {
        p->m_Data = 100;
        }


       
  MessageBox(0, "Hello!", "MsgBox", 0);
 
  //Console Out;

  //Out.Write("Hello World!");
 
  ExitProcess(0);
}

2
Общий раздел / qsort как так отсортировать
« : Сентябрь 18, 2018, 03:03:35 pm »
Приветствую!

Код

typedef struct critter
{
  int number;
  int value;
  char * name;
} critter;

int comp(const void* a, const void* b)
{
        const critter* k = (const critter*)a;
        const critter* m = (const critter*)b;
        int s = ((k -> number) - (m -> number));

        return s;
}

  critter mas[5];
 
  mas[0].number = 5;
  mas[1].number = 4;
  mas[2].number = 3;
  mas[3].number = 2;
  mas[4].number = 1;
 
 
  qsort(mas, 5, sizeof(critter), comp);
 
  for (size_t i = 0; i < 5; i++)
  {
    printf("%d\n", mas.number);
  }


Как перестроить функцию сравнения так, что бы в аргументы можно было передать не только number, но и value

int comp(const void* a, const void* b)
{
        const critter* k = (const critter*)a;
        const critter* m = (const critter*)b;
        int s = ((k -> number) - (m -> number)); // в аргументы функции можно было передать value не изменяя функцию

        return s;
}

Так не надо.
int comp(const void* a, const void* b)
{
        const critter* k = (const critter*)a;
        const critter* m = (const critter*)b;
        int s = ((k -> value) - (m -> value));

        return s;
}

Генерируется код

typedef struct critter_vector
{
  size_t total;
  size_t pos;
  critter * data;
} critter_vector;

int critter_vector_compare_int(const void *a, const void *b)
{
  return *(int *)a - *(int *)b;
}

void critter_vector_sort_int(critter_vector * src)
{
 qsort(src->data, critter_vector_size(src), sizeof(critter), critter_vector_compare_int); //как передать не только number но и value
}

Так как поля critter будут разные. Не понимаю как всё это сделать.

3
Общий раздел / деструкторы С++ и аналог в си
« : Сентябрь 16, 2018, 07:38:37 pm »
Приветствую!

Написал прогу которая генерирует типизированные контейнеры для си. По ходу написания всплыл вопрос о деструкторах.

Код на основе которого генерируется контейнер

typedef struct NAME_vector
{
  size_t total;
  size_t pos;
  TYPE * data;
} NAME_vector;

inline NAME_vector * NAME_vector_new(size_t count)
{
  NAME_vector * p = (NAME_vector*)calloc(1, sizeof(NAME_vector));
 
  p->total = count;
  p->pos   = 0;
  p->data  = (TYPE*)calloc(p->total, sizeof(TYPE));
 
  return p;
}

inline void NAME_vector_clear(NAME_vector * src)
{
  src->pos = 0;
}

inline size_t NAME_vector_size(NAME_vector * src)
{
  return src->pos;
}

inline size_t NAME_vector_capacity(NAME_vector * src)
{
  return src->total;
}

inline TYPE * NAME_vector_get(NAME_vector * src, size_t idx)
{
  assert(idx <= NAME_vector_size(src));

  return &src->data[idx];
}

inline void NAME_vector_free(NAME_vector * src)
{
  for (size_t i = 0; i < NAME_vector_size(src); i++)
  {
    TYPE * j = NAME_vector_get(src, i);
    NAME_destroy(j);
  }
 
  free(src->data);
  free(src);
}

/*
inline void NAME_vector_free(NAME_vector * src)
{
  free(src->data);
  free(src);
}
*/

inline void NAME_vector_set(NAME_vector * src, size_t idx, TYPE val)
{
  memcpy(&src->data[idx], &val, sizeof(TYPE));
}

inline void NAME_vector_resize(NAME_vector * src, size_t count)
{
  if (count > src->total)
  {
    src->total = count;
    src->data  = (TYPE*)realloc(src->data, src->total * sizeof(TYPE));
  }
}

inline void NAME_vector_push_back(NAME_vector * src, const TYPE val)
{
  if (src->pos + 1 > src->total)
  {
    src->total = src->total * 2;
    src->data  = (TYPE*)realloc(src->data, src->total * sizeof(TYPE));
  }

  memcpy(&src->data[src->pos], &val, sizeof(TYPE));
  src->pos++;
}


Код деструктора для вектора

inline void critter_ptr_vector_free(critter_ptr_vector * src)
{
  for (size_t i = 0; i < critter_ptr_vector_size(src); i++)
  {
    critter * j = critter_ptr_vector_get(src, i);
    critter_destroy(j);
  }
 
  free(src->data);
  free(src);
}

Сам код данного объекта

#define critter_max (32)

typedef struct
{
  char * name;
  uint16_t base [critter_max];
  uint16_t bonus[critter_max];
} critter;

void critter_init(critter * src, const char * name)
{
  src->name = strdup(name);

  for (size_t i = 0; i < critter_max; i++)
  {
    src->base = 5;
  }
 
  for (size_t j = 0; j < critter_max; j++)
  {
    src->bonus[j] = 7;
  }
}

void critter_destroy(critter * src)
{
  free(src->name);
}

Вроде все понятно. При уничтожении ветора все объекты будут корректно уничтожены, главное реализовать деструктор для хранимого объекта.

Но если хранить не объекты а указатели на объекты.

typedef struct NAME_ptr_vector
{
  size_t total;
  size_t pos;
  TYPE ** data;
} NAME_ptr_vector;

inline NAME_ptr_vector * NAME_ptr_vector_new(size_t count)
{
  NAME_ptr_vector * p = (NAME_ptr_vector*)calloc(1, sizeof(NAME_ptr_vector));
 
  p->total = count;
  p->pos   = 0;
  p->data  = (TYPE**)calloc(p->total, sizeof(TYPE*));
 
  return p;
}

inline void NAME_ptr_vector_clear(NAME_ptr_vector * src)
{
  src->pos = 0;
}

inline size_t NAME_ptr_vector_size(NAME_ptr_vector * src)
{
  return src->pos;
}

inline size_t NAME_ptr_vector_capacity(NAME_ptr_vector * src)
{
  return src->total;
}

inline TYPE * NAME_ptr_vector_get(NAME_ptr_vector * src, size_t idx)
{
  assert(idx <= NAME_ptr_vector_size(src));

  return src->data[idx];
}

inline void NAME_ptr_vector_free(NAME_ptr_vector * src)
{
  for (size_t i = 0; i < NAME_ptr_vector_size(src); i++)
  {
    TYPE * j = NAME_ptr_vector_get(src, i);
    NAME_destroy(j);
  }
 
  free(src->data);
  free(src);
}

/*
inline void NAME_ptr_vector_free(NAME_ptr_vector * src)
{
  free(src->data);
  free(src);
}
*/

inline void NAME_ptr_vector_set(NAME_ptr_vector * src, size_t idx, TYPE * val)
{
  src->data[idx] = val;
}

inline void NAME_ptr_vector_resize(NAME_ptr_vector * src, size_t count)
{
  if (count > src->total)
  {
    src->total = count;
    src->data  = (TYPE**)realloc(src->data, src->total * sizeof(TYPE*));
  }
}

inline void NAME_ptr_vector_push_back(NAME_ptr_vector * src, TYPE * val)
{
  if (src->pos + 1 > src->total)
  {
    src->total = src->total * 2;
    src->data  = (TYPE**)realloc(src->data, src->total * sizeof(TYPE*));
  }

  src->data[src->pos] = val;
  src->pos++;
}

Генерируется вектор указателей. Код почти аналогичен.

Вопрос в том, что в С++ деструктор для указателей объектов которые находятся в векторе не вызывается автоматически. Для чего это сделано?
Стоит ли в моей реализации поступить так же?

4
Приветствую!

Есть такой код

typedef struct
{
  char * name;
} widget;

void widget_destroy(widget * src)
{
  unised(src);
}

И такой

typedef struct
{
  size_t total;
  size_t pos;
  widget * data;
} widget_vector;

Этот вектор генерируется прогой.

#ifndef _CONTAINERS_widget_H
#define _CONTAINERS_widget_H
typedef struct
{
  size_t total;
  size_t pos;
  widget * data;
} widget_vector;

inline widget_vector * widget_vector_new(size_t count)
{
  widget_vector * p = (widget_vector*)calloc(1, sizeof(widget_vector));
 
  p->total = count;
  p->pos   = 0;
  p->data  = (widget*)calloc(p->total, sizeof(widget));
 
  return p;
}

inline void widget_vector_clear(widget_vector * src)
{
  src->pos = 0;
}

inline size_t widget_vector_size(widget_vector * src)
{
  return src->pos;
}

inline size_t widget_vector_capacity(widget_vector * src)
{
  return src->total;
}

inline widget * widget_vector_get(widget_vector * src, size_t idx)
{
  assert(idx <= widget_vector_size(src));

  return &src->data[idx];
}

inline void widget_vector_free(widget_vector * src)
{
  for (size_t i = 0; i < widget_vector_size(src); i++)
  {
    widget * j = widget_vector_get(src, i);
    widget_destroy(j);
  }
 
  free(src->data);
  free(src);
}

/*
inline void widget_vector_free(widget_vector * src)
{
  free(src->data);
  free(src);
}
*/

inline void widget_vector_set(widget_vector * src, size_t idx, widget val)
{
  memcpy(&src->data[idx], &val, sizeof(widget));
}

inline void widget_vector_resize(widget_vector * src, size_t count)
{
  if (count > src->total)
  {
    src->total = count;
    src->data  = (widget*)realloc(src->data, src->total * sizeof(widget));
  }
}

inline void widget_vector_push_back(widget_vector * src, const widget val)
{
  if (src->pos + 1 > src->total)
  {
    src->total = src->total * 2;
    src->data  = (widget*)realloc(src->data, src->total * sizeof(widget));
  }

  memcpy(&src->data[src->pos], &val, sizeof(widget));
  src->pos++;
}
typedef struct
{
  size_t total;
  size_t pos;
  widget ** data;
} widget_ptr_vector;

inline widget_ptr_vector * widget_ptr_vector_new(size_t count)
{
  widget_ptr_vector * p = (widget_ptr_vector*)calloc(1, sizeof(widget_ptr_vector));
 
  p->total = count;
  p->pos   = 0;
  p->data  = (widget**)calloc(p->total, sizeof(widget*));
 
  return p;
}

inline void widget_ptr_vector_clear(widget_ptr_vector * src)
{
  src->pos = 0;
}

inline size_t widget_ptr_vector_size(widget_ptr_vector * src)
{
  return src->pos;
}

inline size_t widget_ptr_vector_capacity(widget_ptr_vector * src)
{
  return src->total;
}

inline widget * widget_ptr_vector_get(widget_ptr_vector * src, size_t idx)
{
  assert(idx <= widget_ptr_vector_size(src));

  return src->data[idx];
}

inline void widget_ptr_vector_free(widget_ptr_vector * src)
{
  for (size_t i = 0; i < widget_ptr_vector_size(src); i++)
  {
    widget * j = widget_ptr_vector_get(src, i);
    widget_destroy(j);
  }
 
  free(src->data);
  free(src);
}

/*
inline void widget_ptr_vector_free(widget_ptr_vector * src)
{
  free(src->data);
  free(src);
}
*/

inline void widget_ptr_vector_set(widget_ptr_vector * src, size_t idx, widget * val)
{
  src->data[idx] = val;
}

inline void widget_ptr_vector_resize(widget_ptr_vector * src, size_t count)
{
  if (count > src->total)
  {
    src->total = count;
    src->data  = (widget**)realloc(src->data, src->total * sizeof(widget*));
  }
}

inline void widget_ptr_vector_push_back(widget_ptr_vector * src, widget * val)
{
  if (src->pos + 1 > src->total)
  {
    src->total = src->total * 2;
    src->data  = (widget**)realloc(src->data, src->total * sizeof(widget*));
  }

  src->data[src->pos] = val;
  src->pos++;
}
typedef struct
{
  size_t total;
  widget * objs;
  bool * used;
} widget_object_pool;

inline widget_object_pool * widget_object_pool_new(size_t count)
{
  widget_object_pool * p = (widget_object_pool*)calloc(1, sizeof(widget_object_pool));

  p->total = count;
  p->objs  = (widget*)calloc(p->total, sizeof(widget));
  p->used  = (bool*)calloc(p->total, sizeof(bool));
 
  return p;
}

inline void widget_object_pool_free(widget_object_pool * src)
{
  for (size_t i = 0; i < src->total; i++)
  {
    //widget_destroy(&src->objs[i]);
  }
 
  free(src->objs);
  free(src->used);
  free(src);
}

inline bool widget_object_pool_find_free(widget_object_pool * src, size_t * idx)
{
  for (size_t i = 0; i < src->total; i++)
  {
    if (src->used[i] == false)
    {
      *idx = i;
     
      return true;
    }
  }

  return false;
}

inline void widget_object_pool_remove(widget_object_pool * src, widget * val)
{
  size_t i = 0;
 
  while ((i < src->total) && (&src->objs[i] != val))
  {
    i++;
  }

  if (i < src->total)
  {
    src->used[i] = false;
  }
}

inline widget * widget_object_pool_alloc(widget_object_pool * src)
{
  size_t i = 0;

  assert(widget_object_pool_find_free(src, &i));
 
  src->used[i] = true;
   
  return &src->objs[i];
}
typedef struct widget_hash_node
{
  widget data;
  char * key;
  size_t hash;
  struct widget_hash_node * next;
  struct widget_hash_node * prev;
} widget_hash_node;

typedef struct widget_hash_list
{
  struct widget_hash_node * head;
  struct widget_hash_node * tail;
} widget_hash_list;

typedef struct widget_hash
{
  size_t total;
  widget_hash_list * list;
} widget_hash;

inline size_t widget_hash_size(widget_hash * src)
{
  return src->total;
}

inline widget_hash * widget_hash_new(size_t count)
{
  widget_hash * p = (widget_hash*)calloc(1, sizeof(widget_hash));
 
  p->total = count;
  p->list  = (widget_hash_list*)calloc(p->total, sizeof(widget_hash_list));

  return p;
}

inline void widget_hash_list_push_back(widget_hash_list * list, widget_hash_node * elem)
{
  if (list->head == NULL)
  {
    list->head = elem;
    elem->prev = NULL;
  }
  else
  {
    list->tail->next = elem;
    elem->prev = list->tail;
  }

  list->tail = elem;
  elem->next = NULL;
}

inline unsigned int widget_hash_hashed(const char * str)
{
  unsigned int hash = 0;

  for(; *str; str++)
    hash = (hash * 1664525) + (unsigned char)(*str) + 1013904223;

  return hash;
}

inline widget_hash_node * widget_hash_node_new(const char * key, widget data)
{
  widget_hash_node * p = (widget_hash_node*)calloc(1, sizeof(widget_hash_node));
 
  p->hash = widget_hash_hashed(key);
  p->key  = strdup(key);
  memcpy(&p->data, &data, sizeof(widget));
 
  return p;
}

inline widget_hash_node * widget_hash_find_node(widget_hash * src, const char * key)
{
  size_t h = widget_hash_hashed(key) % src->total;
 
  for (widget_hash_node * i = src->list[h].head; i != NULL; i = i->next)
  {
    if (strcmp(i->key, key) == 0)
    {
      return i;
    }
  }

  return NULL;
}

inline void widget_hash_insert(widget_hash * src, const char * key, widget data)
{
  widget_hash_node * i = widget_hash_find_node(src, key);
     unised(data);
  if (i == NULL)
  {
    i = widget_hash_node_new(key, data);
    widget_hash_list_push_back(&src->list[i->hash % src->total], i);
  }
}

inline widget * widget_hash_find(widget_hash * src, const char * key)
{
  widget_hash_node * i = widget_hash_find_node(src, key);
 
  if (i != NULL)
  {
    return &i->data;
  }
 
  return NULL;
}

inline void widget_hash_list_destroy(widget_hash_list * list)
{
  widget_hash_node * curr;
  widget_hash_node * next;

  curr = list->head;

  while (curr != NULL)
  {
next = curr->next;
free(curr);
curr = next;
}

  list->head = NULL;
  list->tail = NULL;
}

inline void widget_hash_free(widget_hash * src)
{
  for (size_t i = 0; i < src->total; i++)
  {
    if (src->list[i].head != NULL)
    {
      widget_hash_list_destroy(&src->list[i]);
    }
  }
}

inline void widget_hash_list_remove(widget_hash_list * list, widget_hash_node * elem)
{
  if (elem == list->head)
  {
    if (elem->next != NULL)
    {
      list->head = elem->next;
      elem->next->prev = NULL;
    }
    else
    {
      list->head = NULL;
    }
  }
  else if (elem == list->tail)
  {
    if (elem->prev != NULL)
    {
      list->tail = elem->prev;
      elem->prev->next = NULL;
    }
    else
    {
      list->tail = NULL;
    }
  }
  else
  {
    elem->next->prev = elem->prev;
elem->prev->next = elem->next;
  }
}
inline widget * widget_new()
{
  widget * p = (widget*)calloc(1, sizeof(widget));
 
  return p;
}
#endif
Каждый в своих h файлах

Но мне нужно что бы работал вот такой код

typedef struct
{
  char * name;
  widget_vector * childs;
} widget;

Как объявить widget так что бы код стал валидным?

#include "widget.h"
#include "containers/containers_widget.h"

Если объявить код так,

#include "containers/containers_widget.h"//widget_vector
#include "widget.h"

Естественно  компилятор ругается на отсутствие widget

В С++ можно так

class widget; и все ок

В си

struct widget; Не работает.

Это мои эксперименты с кодогенерацией.

5
Урочище Флуда / Тихий пк
« : Февраль 21, 2018, 04:50:17 am »
Приветствую.

Есть пк с процессором phenon x4 9550 видеокарта встроенная в маиеринку.
Использую как медиацентр. Установил Коди программа для упорядочивания фильмов них проигрывания. В системнике 3 кулера в блоке питания на кулера процессора и на задней стенке. Шумит хочется сделать тише.

Идея такая убрать из корпуса 2 вентилятора. На боковой стенке напротив проца вырезать дырку для 140 вентилятора проставить его туда на 700 оборотов. Будет дуть в корпус ,и на радиатор проца. Ещё думаю отключить два ядра снизить напряжение с частотой. Как думаете  стоит такое делать или процессор будет перегреваться. Тдп проца 95 вт

6
Общий раздел / Вопросы по С/С++
« : Октябрь 28, 2017, 01:43:42 pm »
Написал код для разбора файла формата:
{номер}{строка}

Пример

{100}{Hello!}

Код на С++

#ifndef _MSG_HPP
#define _MSG_HPP
/*******************************************************************************

*******************************************************************************/
class msg
{
public:
  msg(const string & name);
  ~msg();
  char read_char();
  bool read();
  const string & get();
  const string & str(const string & val);

private:
  size_t   m_line;
  size_t   m_tabs;
  string   m_buffer;
  ifstream m_input;
  map<string, string> m_data;
};
/*******************************************************************************

*******************************************************************************/
msg::msg(const string & name)
{
  m_input.open(name.c_str());
 
  m_line = 1;
  m_tabs = 0;
 
  while(read())
  {
    string f = get();
    read();
    string s = get();
    m_data.insert(pair<string, string>(f,s));
  }
 
  for (map<string,string>::iterator i = m_data.begin(); i != m_data.end(); ++i)
  {
    cout << i->first + " = " + i->second  << endl;
  }
}
/*******************************************************************************

*******************************************************************************/
msg::~msg()
{
  m_input.close();
}
/*******************************************************************************

*******************************************************************************/
char msg::read_char()
{
  char ch = m_input.get();
 
  m_tabs++;
 
  if (ch == '\n')
  {
    m_line++;
    m_tabs = 0;
  }
 
  return ch;
}
/*******************************************************************************

*******************************************************************************/
bool msg::read()
{
  m_buffer.clear();
 
  char ch = read_char();

  while ((ch == ' ') || (ch == '\n'))
  {
    ch = read_char();
  }

  if (ch == '{')
  {
    ch = read_char();

    while (ch != '}')
    {
      if (ch != '\n')
      {
        m_buffer.push_back(ch);
      }
      ch = read_char();
    }
  }
 
  if (ch == EOF)
  {
    return false;
  }
 
  return true;
}
/*******************************************************************************

*******************************************************************************/
const string & msg::get()
{
  return m_buffer;
}
/*******************************************************************************

*******************************************************************************/
const string & msg::str(const string & val)
{
  map<string, string>::iterator i = m_data.find(val);

  if (i == m_data.end())
  {
    return "Error: Not found string in " + val;
  }
  else
  {
    return i->second;
  }
}
/*******************************************************************************

*******************************************************************************/
#endif

Проблема в этой функции

const string & msg::str(const string & val)
{
  map<string, string>::iterator i = m_data.find(val);

  if (i == m_data.end())
  {
    return "Error: Not found string in " + val;
  }
  else
  {
    return i->second;
  }
}

Как вернуть second?

7
Общий раздел / Объясните ООП на пальцах
« : Декабрь 06, 2016, 04:42:42 am »
Оригинал темы здесь http://forum.oberoncore.ru/viewtopic.php?f=12&t=5968

Продублирую сюда, может кто не может на оберкор заходить. Да и сишников полно, Влад и Ляксей. ;)

Приветствую. Давненько я тем не открывал.

Хотелось бы понять ООП, я знаю, что все совеременные языки поддерживают эту парадигму. Но мне хочется понять, как ООП работает изнутри на примере процедурного языка.

Пример С++.
class rect
{
public:
size_t x, y, w, h;
};

class widget
{
public:
private:
rect area;
};

class window: public widget
{
public:
private:
};



Что получилось, window наследует widget/
И теперь в window можно обращаться к классу rect

Теперь пример на си, хотелось бы узнать данный пример соответствует ООП парадигме

typedef struct
{
size_t x;
size_t y;
size_t w;
size_t h;
} gui_rect;

typedef struct
{
gui_rect area;
} gui_widget;

typedef struct
{
gui_widget widget;
} gui_window;

Теперь gui_window тоже обладает полями widget'а

Но обращаться приходится через переменную widget
Пример
gui_window win;
win.widget.area.x
На С++
window win;
win.x

В чём вопрос, я правильно понимаю, что допустим если транслировать С++ в С, то примерно получится тот же код?

#ifndef _LIB_GUI_H
#define _LIB_GUI_H
/*******************************************************************************

*******************************************************************************/
size_t gui_strlen(const char * src)
{
  size_t i = 0;
 
  while (src[i] != 0)
  {
    i++;
  }
 
  return i;
}
/*******************************************************************************

*******************************************************************************/
char * gui_strdup(const char * src)
{
  size_t l = gui_strlen(src);
 
  char * p = (char*)calloc(gui_strlen(src) + 1, sizeof(char));
 
  assert(p);

  memcpy(p, src, l);

  return p;
}
/*******************************************************************************

*******************************************************************************/
size_t gui_strcpy(char * dst, const char * src, size_t maxlen)
{
  const size_t srclen = strlen(src);
 
  if (srclen < maxlen)
  {
    memcpy(dst, src, srclen + 1);
  }
  else if (maxlen != 0)
  {
    memcpy(dst, src, maxlen - 1);
    dst[maxlen - 1] = '\0';
  }

  return srclen;
}
/*******************************************************************************

*******************************************************************************/
size_t gui_strcat(char * dst, const char * src, size_t maxlen)
{
    const size_t srclen = gui_strlen(src);
    const size_t dstlen = gui_strlen(dst);
   
    if (dstlen == maxlen)
    {
      return maxlen+srclen;
    }
   
    if (srclen < maxlen-dstlen)
    {
      memcpy(dst+dstlen, src, srclen+1);
    }
    else
    {
      memcpy(dst+dstlen, src, maxlen-dstlen-1);
      dst[maxlen-1] = '\0';
    }
   
    return dstlen + srclen;
}
/*******************************************************************************

*******************************************************************************/
#define GUI_WIDGET_TYPE_IS_WINDOW  0
#define GUI_WIDGET_TYPE_IS_BUTTON  1
/*******************************************************************************

*******************************************************************************/
typedef struct
{
  size_t x;
  size_t y;
  size_t w;
  size_t h;
} gui_rect;
/*******************************************************************************

*******************************************************************************/
typedef struct gui_list
{
  struct gui_widget * head;
  struct gui_widget * tail;
} gui_list;
/*******************************************************************************

*******************************************************************************/
typedef struct gui_widget
{
  size_t type;
  void * data;
  struct gui_widget * next;
  struct gui_widget * prev;
  gui_list childs;
  gui_rect area;
  char * title;
} gui_widget;
/*******************************************************************************

*******************************************************************************/
typedef struct
{
  gui_widget widget;
} gui_window;
/*******************************************************************************

*******************************************************************************/
typedef struct
{
  gui_widget widget;
} gui_button;
/*******************************************************************************

*******************************************************************************/
void gui_list_push_back(gui_list * list, gui_widget * elem)
{
  assert(list);
  assert(elem);

  if (list->head == NULL)
  {
    list->head = elem;
    elem->prev = NULL;
  }
  else
  {
    list->tail->next = elem;
    elem->prev = list->tail;
  }

  list->tail = elem;
  elem->next = NULL;
}
/*******************************************************************************

*******************************************************************************/
void gui_list_init(gui_list * list)
{
  assert(list);

  list->head = NULL;
  list->tail = NULL;
}
/*******************************************************************************

*******************************************************************************/
size_t gui_widget_get_type(gui_widget * src)
{
  assert(src);

  return src->type;
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_set_type(gui_widget * src, size_t type)
{
  assert(src);

  src->type = type;
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_set_size(gui_widget * src, size_t x, size_t y, size_t w, size_t h)
{
  assert(src);

  src->area.x = x;
  src->area.y = y;
  src->area.w = w;
  src->area.h = h;
}
/*******************************************************************************

*******************************************************************************/
void * gui_widget_get_data(gui_widget * src)
{
  assert(src);

  return src->data;
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_set_data(gui_widget * src, void * ptr)
{
  assert(src);
  assert(ptr);

  src->data = ptr;
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_set_title(gui_widget * src, const char * title)
{
  assert(src);

  if (src->title != NULL)
  {
    free(src->title);
    src->title = NULL;
  }
 
  src->title = gui_strdup(title);
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_get_size(gui_widget * src, gui_rect * dst)
{
  assert(src);

  src->area.x = dst->x;
  src->area.y = dst->y;
  src->area.w = dst->w;
  src->area.h = dst->h;
}
/*******************************************************************************

*******************************************************************************/
size_t gui_widget_get_pos_x(gui_widget * src)
{
  assert(src);

  gui_rect rt;
 
  gui_widget_get_size(src, &rt);

  return rt.x;
}
/*******************************************************************************

*******************************************************************************/
size_t gui_window_get_pos_x(gui_window * src)
{
  assert(src);
  assert(gui_widget_get_type(&src->widget) == GUI_WIDGET_TYPE_IS_WINDOW);
  assert(gui_widget_get_data(&src->widget));
 
  return gui_widget_get_pos_x(&src->widget);
}
/*******************************************************************************

*******************************************************************************/
gui_window * gui_window_new(size_t x, size_t y, size_t w, size_t h, const char * title)
{
  gui_window * p = (gui_window*)calloc(1, sizeof(gui_window));
 
  assert(p);
 
  gui_widget_set_type(&p->widget, GUI_WIDGET_TYPE_IS_WINDOW);
  gui_widget_set_data(&p->widget, p);
  gui_widget_set_size(&p->widget, x, y, w, h);
  gui_widget_set_title(&p->widget, title);
 
  gui_list_init(&p->widget.childs);
 
  return p;
}
/*******************************************************************************

*******************************************************************************/
void gui_widget_attach(gui_widget * dst, gui_widget * src)
{
  assert(dst);
  assert(src);
 
  gui_list_push_back(&dst->childs, src);
}
/*******************************************************************************

*******************************************************************************/
void gui_window_attach_button(gui_window * dst, gui_button * src)
{
  assert(dst);
  assert(src);

  gui_widget_attach(&dst->widget, &src->widget);
}
/*******************************************************************************

*******************************************************************************/
bool gui_point_in_rect(size_t x, size_t y, gui_rect * rect)
{
  return (x > rect->x) && (x < rect->x + rect->w) && (y > rect->y) && (y < rect->y + rect->h);
}
/*******************************************************************************

*******************************************************************************/
gui_widget * gui_widget_contains(gui_widget * widget, size_t x, size_t y)
{
  for (gui_widget * i = widget->childs.head; i != NULL; i = i->next)
  {
    if (gui_point_in_rect(x, y, &i->area))
    {
      return i;
    }
  }

  return NULL;
}
/*******************************************************************************

*******************************************************************************/
#endif

Уточню вопрос, window наследуется от widget, это нужно понимать как window содержит в себе поля widget?

Хочется разобрать по полочкам и понять как делать, закат солнца в ручную. :D Как оно всё в унутрях то работает.

Ещё пример.

typedef struct
{
size_t hex;
} map_object;

typedef struct
{
map_object map_obj;
} critter_object;

typedef struct
{
map_object map_obj;
} item_object;

typedef struct
{
item_object item_obj;
} weapon_object;

size_t weapon_get_hex(weapon_object * obj)
{
return obj->item_obj.map_obj.hex
}

Есть map_object, от него наследуется critter_object и item_object. От item_object наследуется weapon_object.

Если писать в ООП стиле, то в map_object
Будет метод
size_t map_object::get_hex()
{
return hex;
}

И из наследуемых классов так же, можно вызвать get_hex

А в си, сложнее, придётся обращаться к через все поля пример

size_t weapon_get_hex(weapon_object * obj)
{
return obj->item_obj.map_obj.hex
}

Получается ООП так же работает, просто скрывает данные нюансы? Или там всё же посложней реализация?

8
Не как пользоваться библиотеками winapi, qt, gtk, а именно как их сделать.

Как реализовать окно из прямоугольников. Как создавать события для окон кнопок и т.д

С помощью библиотеки sdl, я пробывал сделать gui. Дальше кнопок не пошло. Я скачивал разные исходники библиотек, но они все на ооп.

Как я сделал.

В главном цикле, опрашивается мышь.
Если мышь переместилась, проверить созданные кнопки. Происходит перебор массива кнопок  с их координатами, если курсор на кнопке вывести картинку.

Всё это медленно и грузит процессор. Поэтому хотелось бы почитать книги об этом. Основы, от рисования точки, до окон, кнопок и т.д

9
В реализации компиляторов си, нет проверки границ массива, даже статического.

Данную проверку невозможно реализовать? К примеру размер статического массива вычислить можно. С динамическим массивом поможет функция msize. Почему в компиляторах не реализуют данные проверки?

Страницы: [1]