views:

191

answers:

4

I am developing a simple library in C, for my own + some friends personal use.

I am currently having a C structure with some members that should be somehow hidden from the rest of the application, as their use is only internal. Modifying by accident one of this members will probably make the library 'go wild'.

Is there any 'workaround' to hide those members so that they can't be accessible ?

+9  A: 

The usual techique is this:

/* foo.h */
typedef struct Foo Foo;

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

/* foo.c */
struct Foo {
  int private_var;
};

You can partially hide data members by defining Foo in the header and FooPrivate in the .c file thus:

struct FooPrivate {
  Foo public_stuff;
  int private_var;
}

But then your implementation has to cast back and forth between Foo and FooPrivate, which I find to be a royal PITA, and is a maintenance burden if you change your mind later and want to make something private. Unless you want suck every last CPU cycle out of the code, just use accessor functions.

Marcelo Cantos
Can you please be more specific. :)
Andrei Ciobanu
@nomemory, provide only an interface to update specific fields, do not reveal the structure. Like the foo_create and foo_bark functions, for example.
Nick D
This hides the *entire* contents of the `struct`, not specific fields, so accessors will be necessary.
jleedev
Got it. Thanks!
Andrei Ciobanu
+2  A: 

Marcelo Cantos has already given you the answer. For more detailed information, you should look at how FILE structure is effectively hidden in most of the uderlying libraries.

You would have noticed that the FILE structure in itself is never available to the user, only the interfaces and an Opaque FILE * is available to us.

Jay
+1  A: 

Basically the idea is to rename the variables of the struct with something like a hash and write functions (that would sort of mimmic methods in OO languages) to access them. Ideally you should have function pointers to those functions in your struct so you don't have to call an external function and pass it hte struct who's members you wish to add. However function pointer syntax is not known to be the prettiest. A simple example that may clarify what was said before by Marcelo:

struct Car {
    int _size;
    char _colour[10];

};

typedef struct Car Car;


int main (int argc, char **argv) {   
    Car *myCar= malloc(sizeof(Car));
    myCar->_size=5; /* accessing it directly just to set up a value, you shold have an
                       accessor function really */

    printf("car size is: %i \n",getCarSize(myCar));
    free(myCar);
}




int getCarSize(Car *myCar) {
     return myCar->_size;
}
lordsandwich
+1  A: 

I agree with Marcelo Cantos, but also suggest simply adding a pointer inside the "public" structure, which points to the "private" contents, i.e:

/* foo.h */
typedef struct Bar Bar;
typedef struct Foo 
{
   int public;
   Bar* private;
} Foo;

Foo *foo_create(...);

void foo_bark(Foo* foo, double loudness);

/* foo.c */
struct Bar 
{
  int private_var;
};

This approach is kind of like the "pimpl" ideom. The simplest approach by far is to do what Marcelo Cantos suggested.

S.C. Madsen
Thanks, it seems that C can support some "oop" features with a little effort on the programmer's side :).
Andrei Ciobanu