L
L
LittleBuster2015-10-07 23:27:46
C++ / C#
LittleBuster, 2015-10-07 23:27:46

Does it look like OOP in C?

Is this way of building applications similar to OOP? And is it like inheriting the FileSocket type from 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;
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
Eddy_Em, 2015-10-08
@Eddy_Em

If you want to look at the tin, then I advise you to look through the documentation of GyTyK. It's probably impossible to think of anything worse! The most excellent example of how not to write code.

Z
Zelimkhan Beltoev, 2015-10-08
@Beltoev

It's like a structure in C++ is a kind of class with public fields and methods, while in C a structure can only have fields.
But if you want to pervert, then you can store references to functions inside the structure, and already call them as methods (however, the structure itself will need to be passed as the first parameter).
For example, I'll pull out a piece of code from your listing:

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;
}

G
GavriKos, 2015-10-07
@GavriKos

No, it doesn't look like it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question