-2

i have this issue in C. Let's say, i have a struct like so:

struct Writer {
    char buffer[10];
    void (*writeFunction)(uint8_t*, size_t);
}

This struct has methods that use a user given writer function pointer to dump the values, something like so:

struct Writer writer;
FILE* file = fopen("test.txt", "wb");
void writeToFile(uint8_t* content, size_t size)
{
    fwrite(content, 1, size, file);
}
write.writeFunction = writeToFile;

This works fine, when the user writes the write functions and passes them manually. Is there however a way to automate this, so that i can say, for every new Writer struct, a new writeFunction pointer with a from-user-given-filepath, is generated. I tried, but i keep coming to C++ lambda functions or needing the this pointer from C++.

Expected is something like:

void generate(struct Writer* writer, const char* filename)
{
    // somehow, writer->writerfunction needs to point to a 
writeToFile function like above 
}

Thank you.

darune
  • 10,480
  • 2
  • 24
  • 62
AKJ
  • 950
  • 2
  • 13
  • 18
  • Are you willing to change how you call `writeFunction` to achieve your goal? If you are, take a look at: https://stackoverflow.com/q/17052443/315052 – jxh Nov 12 '19 at 05:45
  • No, that is not possible in standard C, period. – Antti Haapala -- Слава Україні Nov 12 '19 at 06:04
  • I would really like to not have an extra parameter in the writeFunction pointer. (I guess we could always change it to void (*writeFunction)(uint8_t*, size_t, void*), where void" can be reinterpreted as FILE* or left unused. I really hoped we could avoid the "left unused" case altogether, by only having the necessary arguments, which are the size and the content). – AKJ Nov 12 '19 at 06:09
  • @AKJ: There is another parameter that is relevant: the destination of the write itself. – jxh Nov 12 '19 at 21:27

2 Answers2

0

Why not storeFILE * as member of writer structure and pass it to writer function?

struct Writer {
    char buffer[10];
    FILE *file;
    void (*writeFunction)(FILE *, uint8_t*, size_t);
}

void writeToFile(FILE *file, uint8_t* content, size_t size)
{
    fwrite(content, 1, size, file);
}

And generate function becomes.

void generate(struct Writer* writer, const char* filename)
{
   FILE* file = fopen(filename, "wb");
   writer->writeFunction = writeToFile;
   writer->file = file;
}

while calling the function using function pointer,

   (*writer->writeFunction)(writer->file, writer->buffer, somesize);
kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
  • Thanks for the answer, but you are not allowed to change the writeFunction pointer, because it can also not write to FILE, for example, it could simply send the content over HTTP. – AKJ Nov 12 '19 at 06:02
  • @AKJ: See: [dynamic dispatch](http://stackoverflow.com/a/17622474/315052). – jxh Nov 13 '19 at 18:38
  • @jxh Thanks for the link. – AKJ Nov 14 '19 at 19:40
0

This isn't possible with standard c.

The closest you can get to encapsulation is probably to turn the writer struct into a function altogether, ala.

void Writer(char buffer[10], void (*writeFunction)(uint8_t*, size_t));

Now you can add overload if you like and/or check if writeFunction is zero.

darune
  • 10,480
  • 2
  • 24
  • 62