I tried to do data encapsulation in C based on this post here https://alastairs-place.net/blog/2013/06/03/encapsulation-in-c/.
In a header file I have:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
// Pre-declaration of struct. Contains data that is hidden
typedef struct person *Person;
void getName(Person obj);
void getBirthYear(Person obj);
void getAge(Person obj);
void printFields(const Person obj);
#endif
In ´functions.c´ I have defined the structure like that
#include "Functions.h"
enum { SIZE = 60 };
struct person
{
char name[SIZE];
int birthYear;
int age;
};
pluss I have defined functions as well.
In main.c I have:
#include "Functions.h"
#include <stdlib.h>
int main(void)
{
// Works because *Person makes new a pointer
Person new = malloc(sizeof new);
getName(new);
getAge(new);
getBirthYear(new);
printFields(new);
free(new);
return 0;
}
Is it true, that when I use Person new, new is already pointer because of typedef struct person *Person;.
How is it possible, that linker cannot see the body and members that I have declared in my struct person
Is this only possible using pointer?
Is the correct (and only) way to implement OOP prinicples in my case to make a different struct in functions.h like so:
typedef struct classPerson
{ // This data should be hidden
Person data;
void (*fPtrGetName)(Person obj);
void (*fPtrBirthYear)(Person obj);
void (*fPtrGetAge)(Person obj);
void (*fPtrPrintFields)(const Person obj);
} ClassPerson;
First of all, it is usually better to not hide pointers behind a typedef, but to let the caller use pointer types. This prevents all kinds of misunderstandings when reading and maintaining the code. For example void printFields(const Person obj); looks like nonsense if you don't realize that Person is a pointer type.
Have I understood correctly, that when I use Person new, new is already pointer because of typedef struct person *Person;.
Yes. You are confused because of the mentioned typedef.
How is it possible, that linker cannot see the body and members that I have declared in my ´struct person´?
The linker can see everything that is linked, or you wouldn't end up with a working executable.
The compiler however, works on "translation units" (roughly means a .c file and all its included headers). When compiling the caller's translation unit, the compiler doesn't see functions.c, it only sees functions.h. And in functions.h, the struct declaration gives an incomplete type. Meaning "this struct definition is elsewhere".
Is this only possible using pointer?
Yes, it is the only way if you want to do proper OO programming in C. This concept is sometimes called opaque pointers or opaque type.
(Though you could also achieve "poor man's private encapsulation" though the static keyword. Which is usually not really recommended, since it wouldn't be thread-safe.)
Is the correct (and only) way to implement OOP prinicples in my case to make a different struct in functions.h like so:
Pretty much, yeah (apart from the nit-pick about the mentioned pointer typedef). Using function pointers to the public functions isn't necessary though, although that's how you implement polymorphism.
What your example lacks though is a "constructor" and "destructor". Without them the code wouldn't be meaningful. The malloc and free calls should be inside those, and not done by the caller.
With or without typedef, in C you hide data by declaring incomplete types. In /usr/include/stdio.h, you'll find fread(3) takes a FILE * argument:
extern size_t fread (void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __stream) __wur;
and FILE is declared something like this:
struct _IO_FILE;
typedef struct _IO_FILE FILE;
Using stdio.h you cannot define a variable of type FILE, because type FILE is incomplete: it's declared, but not defined. But you can happily pass FILE * around, because all data pointers are the same size. You're just going to have to call fopen(3) to make it point to an open file.
To partially define a type, as in your case:
struct classPerson
{ // This data should be hidden
Person data;
void (*fPtrGetName)(Person obj);
...
};
is a little trickier. First of all, you should have a really good reason, namely that two implementations of fPtrGetName are implemented. Otherwise you're just building complexity on the altar of OOP.
A good example of a good reason is bind(2). You can bind a unix domain socket or a network socket, among others. Both types are represented by struct sockaddr, but that's just a stand-in type for struct sockaddr_un and struct sockaddr_in. Functions that take struct sockaddr depend on the fact that all such structures start with the member sun_family, and branch accordingly. Et voila, polymorphism: one function, many types.
For an example of a struct full of function pointers, I recommend looking at SQLite. Its API is loaded with structures to isolate it from the OS and let the user define plug-ins.
BTW, if I may say so, fPtrGetName is a terrible name. It's not interesting that it's a function pointer and (controversy!) "get" is noise on a function that takes no arguments. Compare
struct classPerson sargent;
sargent.fPtrGetName();
sargent.name();
Which would you rather use? I reserve "get" (or similar) for I/O functions; at least then you're getting something, not just moving it from one pocket to another! For setting, in C++ I overload the function, so that get/set functions have the same name, but in C I wind up with e.g. set_name(const char name[]).
Related
I'm currently a bit confused regarding the concept of information hiding of C-structs.
The backround of this question is an embedded c project with nearly zero knowledge of OOP.
Up until now I always declared my typedef structs inside the header file of the corresponding module.
So every module which wants to use this struct knows the struct type.
But after a MISRA-C check I discovered the medium severity warning: MISRAC2012-Dir-4.8
- The implementation of a structure is unnecessarily exposed to a translation unit.
After a bit of research I discovered the concept of information hiding of C-structs by limiting the visible access of the struct members to private scope.
I promptly tried a simple example which goes like this:
struct_test.h
//struct _structName;
typedef struct _structName structType_t;
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
main.c
#include "struct_test.h"
structType_t myTest;
myTest.varA = 0;
myTest.varB = 1;
myTest.varC = 'c';
This yields the compiler error, that for main.c the size of myTest is unknown.
And of course it is, main.c has only knowledge that a struct of the type structType_t exists and nothing else.
So I continued my research and stumbled upon the concept of opaque pointers.
So I tried a second attempt:
struct_test.h
typedef struct _structName *myStruct_t;
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
main.c
#include "struct_test.h"
myStruct_t myTest;
myTest->varA = 1;
And I get the compiler error: dereferencing pointer to incomplete type struct _structName
So obviously I haven't understood the basic concept of this technique.
My main point of confusion is where the data of the struct object will?
Up until now I had the understanding that a pointer usually points to a "physical" representation of the datatype and reads/writes the content on the corresponding address.
But with the method above, I declare a pointer myTest but never set an address where it should point to.
I took the idea from this post:
What is an opaque pointer in C?
In the post it is mentioned, that the access is handled with set/get interface methods so I tried adding one similiar like this:
void setVarA ( _structName *ptr, int valueA )
{
ptr->varA = valueA;
}
But this also doesn't work because now he tells me that _structName is unknown...
So can I only access the struct with the help of additional interface methods and, if yes, how can I achieve this in my simple example?
And my bigger question still remains where the object of my struct is located in memory.
I only know the pointer concept:
varA - Address: 10 - Value: 1
ptrA - Address: 22 - Value: 10
But in this example I only have
myTest - Address: xy - Value: ??
I have trouble understanding where the "physical" representation of the corresponding myTest pointer is located?
Furthermore I can not see the benefits of doing it like this in relatively small scope embedded projects where I am the producer and consumer of the modules.
Can someone explain me if this method is really reasonable for small to mid scale embedded projects with 1-2 developers working with the code?
Currently it seems like more effort to make all this interface pointer methods than just declaring the struct in my header-file.
Thank you in advance
My main point of confusion is where the data of the struct object will?
The point is that you do not use the struct representation (i.e. its size, fields, layout, etc.) in other translation units, but rather call functions that do the work for you. You need to use an opaque pointer for that, yes.
how can I achieve this in my simple example?
You have to put all the functions that use the struct fields (the real struct) in one file (the implementation). Then, in a header, expose only the interface (the functions that you want users to call, and those take an opaque pointer). Finally, users will use the header to call only those functions. They won't be able to call any other function and they won't be able to know what is inside the struct, so code trying to do that won't compile (that is the point!).
Furthermore I can not see the benefits of doing it like this in relatively small scope embedded projects where I am the producer and consumer of the modules.
It is a way to force modules to be independent of each other. Sometimes it is used to hide implementations to customers or to be able to guarantee ABI stability.
But yes, for internal usage, it is usually a burden (and hinders optimization, since everything becomes a black box to the compiler except if you use LTO etc.). A syntactic approach like public/private in other languages like C++ is way better for that.
However, if you are bound to follow MISRA to such degree (i.e. if your project has to follow that rule, even if it is only advisory), there is not much you can do.
Can someone explain me if this method is really reasonable for small to mid scale embedded projects with 1-2 developers working with the code?
That is up to you. There are very big projects that do not follow that advice and are successful. Typically a comment for private fields, or a naming convention, is enough.
As you've deduced, when using an opaque type such as this the main source file can't access the members of the struct, and in fact doesn't know how big the struct is. Because of this, not only do you need accessor functions to read/write the fields of the struct, but you also need a function to allocate memory for the struct, since only the library source knows the definition and size of the struct.
So your header file would contain the following:
typedef struct _structName structType_t;
structType_t *init();
void setVarA(structType_t *ptr, int valueA );
int getVarA(structType_t *ptr);
void cleanup(structType_t *ptr);
This interface allows a user to create an instance of the struct, get and set values, and clean it up. The library source would look like this:
#include "struct_test.h"
struct _structName
{
int varA;
int varB;
char varC;
};
structType_t *init()
{
return malloc(sizeof(structType_t ));
}
void setVarA(structType_t *ptr, int valueA )
{
ptr->varA = valueA;
}
int getVarA(structType_t *ptr)
{
return ptr->varA;
}
void cleanup(structType_t *ptr)
{
free(ptr);
}
Note that you only need to define the typedef once. This both defines the type alias and forward declares the struct. Then in the source file the actual struct definition appears without the typedef.
The init function is used by the caller to allocate space for the struct and return a pointer to it. That pointer can then be passed to the getter / setter functions.
So now your main code can use this interface like this:
#include "struct_test.h"
int main()
{
structType_t *s = init();
setVarA(s, 5);
printf("s->a=%d\n", getVarA(s));
cleanup(s);l
}
In the post it is mentioned, that the access is handled with set/get interface methods so I tried adding one similiar like this:
void setVarA ( _structName *ptr, int valueA )
{
ptr->varA = valueA;
}
But this also doesn't work because now he tells me that _structName is unknown...
The type is not _structName, but struct _structName or (as defined) structType_t.
And my bigger question still remains where the object of my struct is located in memory.
With this technique, there would be a method which returns the address of such an opaque object. It could be statically or dynamically allocated. There should of course also be a method to free an object.
Furthermore I can not see the benefits of doing it like this in relatively small scope embedded projects where I am the producer and consumer of the modules.
I agree with you.
In my C programming, I use opaque-pointers to struct as a way to enforce abstraction and encapsulation of my code, in that manner :
interface_header.h:
typedef struct s_mytype t_mytype;
defs_header.h:
struct s_mytype
{
/* Actual definition of the struct */
};
My problem I want to use a simple type as t_mytype (char for example), but not inform the interface about that. I can't just use typedef char t_mytype, since that would expose the the internals of the type.
I could just use void pointers, but at the cost of type-checking, and I'd rather avoid that.
Doing two typedef wont work either, since that throw an typedef redefinition with different types from the compiler.
I am also considering doing a struct with only one member, which will be my simple type, but would that be an overkill ?
Thanks for your answers.
You have to make a decision. With code like this:
typedef char myHandle;
frobnicate(myHandle *obj);
you already document the intent that client code should only use pointers to myHandle and never assume anything about the underlying type, so you should be able to change the typedef later -- unless there's "sloppy" client code making assumptions it shouldn't.
If you want to completely hide what's behind myHandle, a struct is your only option in C:
typedef struct myHandle myHandle;
frobnicate(myHandle *obj);
and only in a private header or implementation file, you will put
struct myHandle
{
char val;
};
The first option is simpler because inside the implementation of frobnicate(), you can access your value simply using *obj while the second option requires to write obj->val. What you gain with the second version is that you force client code to be written correctly.
In terms of the resulting executable, both versions are equivalent.
I want to create an API for setting and getting fields of a structure in an opaque way (clients should only deal with pointers to them and pass them to the methods declared in the header files). Standard stuff, you define your structures inside the library's source files and do
typedef struct __internal_struct shiny_new_opaque_type;
Problem is that at the moment, the class is simply a wrapper around an already existing API (that will change soon). So the structures I need to use are defined in other header files (full structure declaration is there, the one I want to hide from my clients, so any attempt to dereference a pointer and access a structure member will result in a compiler error). Hence, I don't want to include those headers in my header (only in the .c files). I see three possible ways of dealing with it.
Instead of
typedef struct __internal_struct shiny_new_opaque_type;
do
typedef void shiny_new_opaque_type;
and have my methods do pointer casting. This is dangerous since the compiler can't do type checks.
Copy paste the structure definitions I'm currently using under a new struct __internal_struct (eventually I'll have to define my own struct anyway). Maybe this is the best option?
Define my __internal_struct for now to include a single member that is the corresponding structure from the other API I'm using and use that. Kind of ugly...
Basically is there a way to typedef one structure to another or use an already defined structure as an anonymous member inside another, so that at the end of the day both structures are equivalent? Neither of the following works:
typedef struct transparent_struct struct __internal_struct;
struct __internal_struct
{
struct transparent; // anonymous, direct access to its members
}
EDIT:
From the comments, seems to me that 3, or a variation thereof, would be the way to go. There is also the possibility of never defining my struct, as #Akira pointed out. So
In header: typedef struct my_type; // never defined
And in my source always use it with a cast (struct transparent*)my_type_ptr
In header: typedef struct _internal_struct my_type;
And in source files:
struct _internal_struct {
struct transparent t;
}
Then I can either one of those:
my_type_ptr->t.member
((struct transparent*)my_type_ptr)->member
If you are planning to use opaque pointers, you should provide only an incomplete struct type to users and let them do the operations through the provided functions where one the parameters is a pointer to your incomplete struct type.
For example, let's consider that we have an API which provides a struct foo type and a void print(struct foo*) function to print the content of struct foo instances. A wrapper can be implemented as follows:
wrapper.h
#ifndef WRAPPER_H
#define WRAPPER_H
struct my_obj; /* incomplete type, but you can use pointers to it */
struct my_obj* create(void); /* creates new struct my_obj instance */
void destroy(struct my_obj*); /* deletes the pointed struct my_obj instance */
void set_name_and_id(struct my_obj*, const char*, unsigned);
void show(struct my_obj*);
#endif /* WRAPPER_H */
wrapper.c
#include "wrapper.h"
#include "api.h" /* API only included here */
#include <stdlib.h>
#include <string.h>
#define TO_FOO(my_ptr) ((struct foo*)my_ptr)
struct my_obj* create(void) {
return calloc(1, sizeof(struct foo)); /* allocates memory for 'struct foo' */
}
void destroy(struct my_obj* obj) {
free(obj);
}
void set_name_and_id(struct my_obj* obj, const char* name, unsigned id) {
strcpy(TO_FOO(obj)->bar, name);
TO_FOO(obj)->baz = id;
}
void show(struct my_obj* obj) {
print(TO_FOO(obj)); /* accepts only 'struct foo' pointers */
}
Live Demo
When users include the wrapper.h from the example above, they won't see the api.h and won't be able to dereference the pointer to struct my_obj because it's an incomplete type.
To respond to your comment:
In this case both the internal_struct and the api one are of the same size, aligned and I can either access the api's members using internal_struct->api.member or ((struct API*)internal_struct)->member. What's your view on those two options?
According to N1570 draft (c11):
6.7.2.1 Structure and union specifiers
15 (...) A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.
So, both of your approaches are good and safe, it's up to you which one you like. Using internal_struct->api.member is clear, I would use this version.
Converting comments into an answer.
Avoid option 1 — the API shouldn't use void pointers because of the lack of type safety. C is bad enough as it is; don't go out of your way to drive holes through what type safety is available. If the interface type is struct SomeThing *, you can pass a void * to the function without wittering from the C compiler, but you can't pass a struct SomeThingElse * to the function (without a cast, but needing to add a cast should raise warning flags in your mind). If the API uses void *, you can pass any pointer type to the function without any casts or warnings; that's highly undesirable.
Option 2 is a maintenance liability, if not nightmare. Don't go there.
Therefore, option 3 is the way to go. You have two sub-options.
3A — your structure simply contains a single member that is a pointer to the API's structure type (struct internal_struct { struct API *api; }), and
3B — your structure simply contains a single member that is the API's structure type (struct internal_struct { struct API api; }) — the difference is the presence or absence of the *.
Both 3A and 3B work; which works better for you depends on the organization of the API you're working with — how near to opaque it treats its structure type. The more nearly opaque the structure type, the more appropriate 3A is. On the other hand, it incurs some overhead in accessing the data.
Indeed I ended up going with option 3B. In this case both the internal_struct and the api one are of the same size, aligned and I can either access the api's members using internal_struct->api.member or ((struct API*)interna_struct)->member. What's your view on those two options?
While the version with the cast works, it sucks as notation. Avoid casts whenever you can — they're a bludgeon that tells the compiler "I know better than you do what I'm doing". I avoid casts as much as possible. Yes, I sometimes use casts; that's almost unavoidable. But I avoid them when possible, and this is a case where it's eminently possible.
Using option 3B, the chances are the compiler generates the same code for both internal_struct->api.member and ((struct API *)internal_struct)->member. So, use the cleaner notation — which is also more succinct. There's a mild nuisance from repeating the api.; there's a bigger nuisance from adding parentheses and repeating struct API *.
If you did the cast once:
struct API *api_ptr = (struct API *)internal_struct;
and then used api_ptr->member etc throughout, that might be sensible, but the castless version would still be better.
struct API *api_ptr = &internal_struct->api;
I have a C project that is designed to be portable to various (PC and embedded) platforms.
Application code will use various calls that will have platform-specific implementations, but share a common (generic) API to aid in portability. I'm trying to settle on the most appropriate way to declare the function prototypes and structures.
Here's what I've come up with so far:
main.c:
#include "generic.h"
int main (int argc, char *argv[]) {
int ret;
gen_t *data;
ret = foo(data);
...
}
generic.h: (platform-agnostic include)
typedef struct impl_t gen_t;
int foo (gen_t *data);
impl.h: (platform-specific declaration)
#include "generic.h"
typedef struct impl_t {
/* ... */
} gen_t;
impl.c: (platform-specific implementation)
int foo (gen_t *data) {
...
}
Build:
gcc -c -fPIC -o platform.o impl.c
gcc -o app main.c platform.o
Now, this appears to work... in that it compiles OK. However, I don't usually tag my structures since they're never accessed outside of the typedef'd alias. It's a small nit-pick, but I'm wondering if there's a way to achieve the same effect with anonymous structs?
I'm also asking for posterity, since I searched for a while and the closest answer I found was this: (Link)
In my case, that wouldn't be the right approach, as the application specifically shouldn't ever include the implementation headers directly -- the whole point is to decouple the program from the platform.
I see a couple of other less-than-ideal ways to resolve this, for example:
generic.h:
#ifdef PLATFORM_X
#include "platform_x/impl.h"
#endif
/* or */
int foo (struct impl_t *data);
Neither of these seems particularly appealing, and definitely not my style. While I don't want to swim upstream, I also don't want conflicting style when there might be a nicer way to implement exactly what I had in mind. So I think the typedef solution is on the right track, and it's just the struct tag baggage I'm left with.
Thoughts?
Your current technique is correct. Trying to use an anonymous (untagged) struct defeats what you're trying to do — you'd have to expose the details of definition of the struct everywhere, which means you no longer have an opaque data type.
In a comment, user3629249 said:
The order of the header file inclusions means there is a forward reference to the struct by the generic.h file; that is, before the struct is defined, it is used. It is unlikely this would compile.
This observation is incorrect for the headers shown in the question; it is accurate for the sample main() code (which I hadn't noticed until adding this response).
The key point is that the interface functions shown take or return pointers to the type gen_t, which in turn maps to a struct impl_t pointer. As long as the client code does not need to allocate space for the structure, or dereference a pointer to a structure to access a member of the structure, the client code does not need to know the details of the structure. It is sufficient to have the structure type declared as existing. You could use either of these to declare the existence of struct impl_t:
struct impl_t;
typedef struct impl_t gen_t;
The latter also introduces the alias gen_t for the type struct impl_t. See also Which part of the C standard allows this code to compile? and Does the C standard consider that there are one or two struct uperms entry types in this header?
The original main() program in the question was:
int main (int argc, char *argv[]) {
int ret;
gen_t data;
ret = foo(&data);
…
}
This code cannot be compiled with gen_t as an opaque (non-pointer) type. It would work OK with:
typedef struct impl_t *gen_t;
It would not compile with:
typedef struct impl_t gen_t;
because the compiler must know how big the structure is to allocate the correct space for data, but the compiler cannot know that size by definition of what an opaque type is. (See Is it a good idea to typedef pointers? for typedefing pointers to structures.)
Thus, the main() code should be more like:
#include "generic.h"
int main(int argc, char **argv)
{
gen_t *data = bar(argc, argv);
int ret = foo(data);
...
}
where (for this example) bar() is defined as extern gen_t *bar(int argc, char **argv);, so it returns a pointer to the opaque type gen_t.
Opinion is split over whether it is better to always use struct tagname or to use a typedef for the name. The Linux kernel is one substantial body of code that does not use the typedef mechanism; all structures are explicitly struct tagname. On the other hand, C++ does away with the need for the explicit typedef; writing:
struct impl_t;
in a C++ program means that the name impl_t is now the name of a type. Since opaque structure types require a tag (or you end up using void * for everything, which is bad for a whole legion of reasons, but the primary reason is that you lose all type safety using void *; remember, typedef introduces an alias for an underlying type, not a new distinct type), the way I code in C simulates C++:
typedef struct Generic Generic;
I avoid using the _t suffix on my types because POSIX reserves the _t for the implementation to use* (see also What does a type followed by _t represent?). You may be lucky and get away with it. I've worked on code bases where types like dec_t and loc_t were defined by the code base (which was not part of the implementation — where 'the implementation' means the C compiler and its supporting code, or the C library and its supporting code), and both those types caused pain for decades because some of the systems where the code was ported defined those types, as is the system's prerogative. One of the names I managed to get rid of; the other I didn't. 'Twas painful! If you must use _t (it is a convenient way to indicate that something is a type), I recommend using a distinctive prefix too: pqr_typename_t for some project pqr, for example.
* See the bottom line of the second table in The Name Space in the POSIX standard.
This is unfortunately defined in some external library: cannot touch!
// library.h
typedef struct {
long foo;
char *bar;
/* ... (long & complex stuff omitted) */
} *pointer_to_complex_struct_t;
Now The Question: how to declare an complex_struct_t variable?
Ideal solution but not allowed! (cannot change external library):
// library.h
/* ... (long & complex stuff omitted) */
} complex_struct_t, *pointer_to_complex_struct_t;
// my.h
extern complex_struct_t my_variable;
Non-portable solution (gcc):
// my.h
extern typeof( * (type_placeholder)0 ) my_variable; // Thanks caf!
Other? Better? Thanks!
Bonus question: same question for a function pointer (in case there is any difference; I doubt it).
ADDED bonus: below is the exact same question but with functions instead of structs. This should not make any difference to the short answer ("No."), the only answer I was initially interested in. I did not expect some people to die trying to know and get my job done with creative workarounds, which is why I simplified the question from functions to structs (function pointers have special implicit conversion rules for convenience and confusion). But hey, why not? Let's get the copy-paste workaround competition started. Some workarounds are probably better than others.
///// library.h //////
// Signature has been simplified
typedef double (*ptr_to_callback_t)(long, int, char *);
// Too bad this is not provided: typedef double callback_t(long, int, char *);
///// my.h /////
// This avoids copy-paste but is not portable
typedef typeof( * (ptr_to_callback_t)0 ) callback_t;
extern callback_t callback_1;
extern callback_t callback_2;
extern callback_t callback_3;
// etc.
Short answer = no, there is currently no portable alternative to typeof
A basic copy-paste workaround works OK for functions but not for structs. The compiler will match the duplicated function types, but will not relate the duplicated struct types: a cast is required and the duplicated struct types will diverge without compilation warning.
No, unfortunately you cannot do it with standard C. With C++ a simple metafunction would do the trick though.
However you could just copy-paste the definition of the struct thus leaving the original untouched
typedef struct {
///same struct
} complex_struct_t;
The downside of this solution is that the expression &complex_struct_t won't be of type pointer_to_complex_struct_t, instead it will be of type pointer to unnamed struct {//your members};
You'll need reinterpret_casting, if you need that feature...
As written, the answer to your question is "no"; if all you have is a type definition of
typedef struct {...} *ptr_to_struct;
then there's no (standard, portable) way to extract the struct type. If you have to create an instance of the struct, the best you will be able to do is
ptr_to_struct s = malloc(sizeof *s);
and then refer to the fields in the struct using the -> component selection operator (or by dereferencing s and using the . operator, but you don't want to do that).
You asked if the same thing applied to function pointers; you really need to state exactly what you mean. If you have a situation like
typedef struct {...} *ptr_to_struct;
ptr_to_struct foo() {...}
then the situation is exactly like the above; you don't have a way to declare a variable of that type.
Make a local copy of the header file and include it instead of the original. Now you can do anything you want. If this library could change (update or anything else), you could write a little script to automate these steps and call it from your makefile whenever you compile. Just make sure to not blindly paste into the header, search for the specific line (} *pointer_to_complex_struct_t;) and throw an error if it is no longer found.
Maybe you have to be a bit careful with the search paths for includes if this header uses other headers of this library. Plus, with the order of includes if itself is included by other headers.
EDIT (for your real goal mentioned in a comment): You can't do this with function pointers. Just write the function you want with the signature of the typedef, and it will be compatible to the pointer and can be called by it.
How about:
pointer_to_complex_struct_t newStruct ( void ) {
pointer_to_complex_struct_t ptr =
(pointer_to_complex_struct_t) malloc ( sizeof (*pointer_to_complex_struct_t) );
return ptr;
}
You'd have to reference your newly created struct through ptr-> but you could create new ones.
Of course, this may or may not work, depending on how the struct is actually used. The example that comes to mind is: what if the struct ends with
char data[0];
and data is used to point into the memory following the structure.