![](/i/fill.gif) |
![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
This seems a bit of a stumper to me.
I'm trying to set up a simple class (for testing) that just initializes
directfb. So I have this header file:
class dfbScreen
{
IDirectFB* dfb;
IDirectFBScreen* screen;
IDirectFBFont* font;
....
public:
void openscreen();
void closescreen();
dfbScreen(); ~dfbScreen();
}
Now, of course, the implementation of those need to know the actual
declarations of IDirectFB, IDirectFBFont, and so on. But everything in
DirectFB is done with pointers, so you never actually declare a IDirectFB
value as a value, only as a pointer.
So what do I need to put before "class dfbScreen" such that I can include
just that class header file (without #include <directfb.h>) such that it
compiles, given that directfb.h includes lines like
typedef struct _IDirectFB IDirectFB;
typedef struct _IDirectFBFont IDirectFBFont;
and so on?
If I put "class IDirectFB;" in front, it tells me that's a redeclaration
when I include <directfb.h>. If I don't, it tells me IDirectFB isn't defined.
What I'm doing right now is declaring
struct _IDirectFB; struct _IDirectFBFont; ...
class dfbScreen {
struct _IDirectFB* dfb;
struct _IDirectFBFont* font;
...
}
But that seems wrong, given that I have to grope around in someone else's
headers to pull out private declarations to make it possible to compile a
header that doesn't depend on those declarations.
I tried googling, but I didn't really find any clear answer.
The other choice is to make it into a separate class and add another level
of indirection, but that too seems like a solution to what shouldn't be a
problem?
--
Darren New, San Diego CA, USA (PST)
I ordered stamps from Zazzle that read "Place Stamp Here".
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
You stumbled across a limitation of C++: You cannot pre-declare typedeffed
types because typedef doesn't create a real type, and there's currently no
way of saying that "xyz is a typedeffed name, but don't mind what it actually
is an alias for" (like you can do for classes and structs).
I'm afraid there are only ugly solutions to that problem. The least ugly
of them would be to simply #include that header.
(A very ugly solution would be to use void pointers, and then reinterpret
cast them as needed. But if you are determined to not to have to #include
that header, then that's something that would work.)
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp <war### [at] tag povray org> wrote:
> (A very ugly solution would be to use void pointers, and then reinterpret
> cast them as needed. But if you are determined to not to have to #include
> that header, then that's something that would work.)
I thought of another uglyish kludge that might work and, while kludgey,
not necessarily as ugly as the void pointers:
// Header:
class dfbScreen
{
class MyIDirectFB
MyIDirectFB* dfb;
...
};
// Source file:
class dfbScreen::MyIDirectFB: public IDirectFB
{
/* If IDirectFB supports copying, you can just implement a constructor
here which takes an instance of type IDirectFB in order to initialize
objects of type MyIDirectFB, like:
MyIDirectFB(const IDirectFB& init): IDIrectFB(init) {}
If IDirectFB does not support copying, then you'll have to replicate
its constructors here. No way of automatizing that until the next C++
standard gets implemented in compilers.
*/
};
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> I'm afraid there are only ugly solutions to that problem. The least ugly
> of them would be to simply #include that header.
Yeah. This is supposed to support numerous underlying technologies, so
including that header would fail when that class started using something
other than DFB. For now, putting the "struct _IDirectFB" into the private
part is probably better.
> (A very ugly solution would be to use void pointers, and then reinterpret
> cast them as needed. But if you are determined to not to have to #include
> that header, then that's something that would work.)
Before that, i'd just add an extra layer of indirection to my own private
type that was just the pile of pointers.
> class dfbScreen::MyIDirectFB: public IDirectFB
I'm not sure what this means, but I'm pretty sure it's not going to work
well. :-) DirectFB is all built on top of C, with fake OO stuff, so there's
no way to get one of these for real.
Anyway, thanks for your help. I've got a satisfactory kludge. I was just
hoping there was something less obviously kludgey I was missing.
--
Darren New, San Diego CA, USA (PST)
I ordered stamps from Zazzle that read "Place Stamp Here".
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New schrieb:
>
> What I'm doing right now is declaring
> struct _IDirectFB; struct _IDirectFBFont; ...
> class dfbScreen {
> struct _IDirectFB* dfb;
> struct _IDirectFBFont* font;
> ...
> }
>
> But that seems wrong, given that I have to grope around in someone
> else's headers to pull out private declarations to make it possible to
> compile a header that doesn't depend on those declarations.
Yes, that's why you normally /do/ include the headers... after all,
that's what they are for.
I'm not sure, but you might also be able to directly use
struct IDirectFB;
instead of
class IDirectFB;
> The other choice is to make it into a separate class and add another
> level of indirection, but that too seems like a solution to what
> shouldn't be a problem?
Unfortunately, C++ doesn't natively make a good job at separating
interface from implementation (the bane of allowing direct access to
data members, and "inlining" of classes as data members).
Speaking of interfaces, you might make dfbScreen abstract (serving as
what would usually be declared as an interface in Java), so that you can
keep the actual implementation of it in the background - private data
members included.
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Darren New <dne### [at] san rr com> wrote:
> > class dfbScreen::MyIDirectFB: public IDirectFB
> I'm not sure what this means, but I'm pretty sure it's not going to work
> well. :-) DirectFB is all built on top of C, with fake OO stuff, so there's
> no way to get one of these for real.
Why wouldn't it work? dfbScreen::MyIDirectFB *is* IDirectFB (this is OOP,
after all). Wherever an object of type IDirectFB is expected, you can pass
a pointer to an object of type dfbScreen::MyIDirectFB. And yes, even if you
are passing it to a C function.
Just to make sure, I made a complete test to see that, indeed, it works:
/*-----------------------------------------------------------
SomeCStruct.h
-----------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
struct SomeCStruct
{
int i, j;
};
void someCFunction(struct SomeCStruct* object);
#ifdef __cplusplus
}
#endif
/*-----------------------------------------------------------*/
/*-----------------------------------------------------------
SomeCStruct.c
-----------------------------------------------------------*/
#include "SomeCStruct.h"
#include <stdio.h>
void someCFunction(struct SomeCStruct* object)
{
printf("i=%i, j=%i\n", object->i, object->j);
}
/*-----------------------------------------------------------*/
//-----------------------------------------------------------
// MyClass.hh
//-----------------------------------------------------------
class MyClass
{
class SomeCStructWrapper;
SomeCStructWrapper* obj;
MyClass(const MyClass&);
MyClass& operator=(const MyClass&);
public:
MyClass();
~MyClass();
void foo();
};
//-----------------------------------------------------------
//-----------------------------------------------------------
// MyClass.cc
//-----------------------------------------------------------
#include "MyClass.hh"
#include "SomeCStruct.h"
class MyClass::SomeCStructWrapper: public SomeCStruct
{
public:
SomeCStructWrapper(const SomeCStruct& init): SomeCStruct(init) {}
};
MyClass::MyClass()
{
SomeCStruct instance = { 5, 10 };
obj = new SomeCStructWrapper(instance);
}
MyClass::~MyClass()
{
delete obj;
}
void MyClass::foo()
{
someCFunction(obj);
}
//-----------------------------------------------------------
//-----------------------------------------------------------
// test.cc
//-----------------------------------------------------------
#include "MyClass.hh"
int main()
{
MyClass obj;
obj.foo();
}
//-----------------------------------------------------------
Compiled with:
gcc -Wall -O3 -c SomeCStruct.c
g++ -Wall -O3 MyClass.cc test.cc SomeCStruct.o
Works just fine.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Here's another idea - a bit kludgey as well, but what the heck:
struct MyIDirectFB;
class dfbScreen
{
MyIDirectFB* dfb;
...
};
and in your .cpp:
struct MyIDirectFB
{
IDirectFB data;
};
Requires a bit more effort in coding, but as I said: what the heck...
Or you might cheat a bit on the compiler, using something like:
#ifndef _DIRECTFB_H__INCLUDED_
// (or whatever symbol directfb uses in the header)
struct IDirectFB;
#end
class dfbScreen
{
IDirectFB* dfb;
...
};
and include <directfb> from your implementation instead of from your
header file.
There's more than one way to skin a cat...
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka <ano### [at] anonymous org> wrote:
> Here's another idea - a bit kludgey as well, but what the heck:
> struct MyIDirectFB;
> class dfbScreen
> {
> MyIDirectFB* dfb;
> ...
> };
> and in your .cpp:
> struct MyIDirectFB
> {
> IDirectFB data;
> };
Inheritance achieves the exact same thing, except that it makes MyIDirectFB
to be of type IDirectFB directly.
--
- Warp
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
Warp wrote:
> Darren New <dne### [at] san rr com> wrote:
>> > class dfbScreen::MyIDirectFB: public IDirectFB
>
>> I'm not sure what this means, but I'm pretty sure it's not going to work
>> well. :-) DirectFB is all built on top of C, with fake OO stuff, so there's
>> no way to get one of these for real.
>
> Why wouldn't it work?
I'm not sure what I was thinking of. I'll have to look at this again (and
look up some syntax to see what "x::y : z" means :-) when I'm not at the end
of a day.
--
Darren New, San Diego CA, USA (PST)
I ordered stamps from Zazzle that read "Place Stamp Here".
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
clipka wrote:
> Darren New schrieb:
>>
>> What I'm doing right now is declaring
>> struct _IDirectFB; struct _IDirectFBFont; ...
>> class dfbScreen {
>> struct _IDirectFB* dfb;
>> struct _IDirectFBFont* font;
>> ...
>> }
>>
>> But that seems wrong, given that I have to grope around in someone
>> else's headers to pull out private declarations to make it possible to
>> compile a header that doesn't depend on those declarations.
>
> Yes, that's why you normally /do/ include the headers... after all,
> that's what they are for.
It seems wrong that I should have to expose the DirectFB declarations to
classes that don't care about the directfb declarations, simply because the
private parts of one of the classes they use has a pointer to something in
the directfb libs. That's what's the "seems wrong" part.
> I'm not sure, but you might also be able to directly use
> struct IDirectFB;
IDirectFB isn't a struct or a class. It's a typedef. Therein lies the problem.
> Unfortunately, C++ doesn't natively make a good job at separating
> interface from implementation (the bane of allowing direct access to
> data members, and "inlining" of classes as data members).
Yeah. Plus having to declare everything *and* define it.
> Speaking of interfaces, you might make dfbScreen abstract (serving as
> what would usually be declared as an interface in Java), so that you can
> keep the actual implementation of it in the background - private data
> members included.
What I did for the "real" library interface was to have a Player and a
Player_p object, and the Player.h forward-declared Player_p and the
Player.cpp included the actual definition. It's just an extra level of
indirection and another header file and such, which seemed unnecessary for a
unit-test helper function. (Only the fact that I expect to have to do unit
tests for multiple GUI bits drove me to make it separate from the unit tests
to start with, and then I got sidetracked down to figuring out how to do it
better. :-)
--
Darren New, San Diego CA, USA (PST)
I ordered stamps from Zazzle that read "Place Stamp Here".
Post a reply to this message
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
| ![](/i/fill.gif) |
|
![](/i/fill.gif) |