LittleBuster
@LittleBuster

Похоже ли это на ООП в Си?

Похож ли такой способ построения приложений на ООП? И похоже ли это на наследование типа FileSocket от HsaSocket?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef void (*new_session)(void *ctx, const char *message);

/*
 * low level
 */
typedef struct {
    void *context;
    int sock;
    new_session new_ses;
} HsaSocket;


HsaSocket *hsa_socket_new(void) 
{
    HsaSocket *s = NULL;
    s = (HsaSocket *)malloc(sizeof(HsaSocket));
    return s;
}

/* session function setter */
static inline void hsa_socket_set_signal(HsaSocket *s, new_session ses)
{
    s->new_ses = ses;
}

/* context setter */
static inline void hsa_socket_set_context(HsaSocket *s, void *ctx)
{
    s->context = ctx;
}

void hsa_socket_start_server(HsaSocket *s)
{
	if (s->new_ses != NULL)
    	s->new_ses(s->context, "server started");
}

void hsa_socket_send(HsaSocket *s, const char *data)
{
    printf("%d %s", s->sock, data);
}

void hsa_socket_free(HsaSocket *s)
{
	free(s);
}


/*
 * Other abstraction level with new functional
 */
typedef struct {
    HsaSocket *h_s;
} FileSocket;


FileSocket *file_socket_new(void) {
    FileSocket *fs = NULL;

    fs = (FileSocket *)malloc(sizeof(FileSocket));
    fs->h_s = hsa_socket_new();

    return fs;
}

void file_socket_send_file(FileSocket *fs, const char *fname)
{
    //hsa_socket_send(fs->h_s, /*some data*/);
    //hsa_socket_recv(fs->h_s, /*some data*/);
}

void file_socket_recv_file(FileSocket *fs, const char *fname)
{    
    //hsa_socket_recv(fs->h_s, /*some data*/);
    //hsa_socket_send(fs->h_s, /*some data*/);
}

static inline void file_socket_start_server(FileSocket *fs)
{
    hsa_socket_start_server(fs->h_s);
}

static inline void file_socket_set_signal(FileSocket *fs, new_session ses)
{
    hsa_socket_set_signal(fs->h_s, ses);
}

static inline void file_socket_set_context(FileSocket *fs, void *ctx)
{
    hsa_socket_set_context(fs->h_s, ctx);
}

static inline void file_socket_send(FileSocket *fs, const char *data)
{
    hsa_socket_send(fs->h_s, data);
}

static inline void file_socket_free(FileSocket *fs) {
	hsa_socket_free(fs->h_s);
	free(fs);
}


/*
 * Main App
 */
 typedef struct {
 	FileSocket *fs;
 	//WebCam *cam;
 	//Compressor *cmp;

 	char ip[16];
 	unsigned port;
 } App;



 App *app_new(void)
 {
 	App *app = NULL;

 	app = (App *)malloc(sizeof(App));
 	app->fs = file_socket_new();

 	return app;
 }

/* Handler */
 void app_on_new_session(App *app, const char *message)
 {
 	printf("%s %s\n", message, app->ip);
 }

 static inline void _ses_sig(void *ctx, const char *message)
 {
 	App *app = (App *)ctx;
 	app_on_new_session(app, message);
 }

 void app_start(App *app)
 {
 	/* init */
 	file_socket_set_context(app->fs, (void *)app);
 	file_socket_set_signal(app->fs, _ses_sig);

 	/* start server */
 	file_socket_start_server(app->fs);

 	//file_socket_send(app->fs, /* some system information */);
 	//file_socket_send(app->fs, /* data about file */);
 	//file_socket_send_file(app->fs, "fsdfsd.dat");
 }

void app_free(App *app)
{
	file_socket_free(app->fs);
	free(app);
}



int main(void)
{
	App *app = app_new();
	app_start(app);
	app_free(app);
    return 0;
}
  • Вопрос задан
  • 561 просмотр
Пригласить эксперта
Ответы на вопрос 3
@Eddy_Em
Если хочется посмотреть на жесть, то советую полистать документацию ГыТыКа. Уж хуже придумать, наверное, невозможно! Самый отличный образец того, как не надо писать код.
Ответ написан
@Beltoev
Живу в своё удовольствие
Как бы структура в С++ - это своего рода класс с публичными полями и методами, в то время, как в Си структура может иметь только поля.

Но если хотите поизвращаться, то можно внутри структуры хранить ссылки на функции, а уже их вызывать как методы (правда, первым параметром нужно будет саму структуру передавать).

Например, вырву кусок кода из вашего листинга:
typedef struct {
	// какой-то код
	// указатель на функцию - "метод" класса
	void (*start)(struct app*);
 } App;

 void app_start(App *app)
 {
	// какой-то код
 }

 App *app_new(void)
 {
	// какой-то код
	// собственно, задаем адрес функции
	app->start = &app_start;

 	return app;
 }

int main(void)
{
	App *app = app_new();
	// Вуаля - вызываем как метод класса
	app.start(&app);
	return 0;
}
Ответ написан
Комментировать
GavriKos
@GavriKos
Нет, непохоже.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы