So I'm going through the first tutorial in O'Reilly's iPhone 3D Programming book. At this point in the tutorial, it pulls all the OpenGL ES stuff into a seperate c++ interface. I have followed the book to the letter, as far as I can tell, yet I can't seem to figure out this compiler error. I'm fairly new to C++ (mostly C# in the past), so I'm sure it's something stupid.
Below is the current state of all the relevant files.
I have a c++ header file called IRenderingEngine.hpp with the following contents:
enum DeviceOrientation {
Unknown,
Portrait,
PortraitUpsideDown,
LandscapeLeft,
LandscapeRight,
FaceUp,
FaceDown,
};
struct IRenderingEngine* CreateRenderer1();
struct IRenderingEngine {
virtual void Initialize(int width, int height) = 0; //Compiler error "expected specifier-qualifier-list before 'virtual'
virtual void Render() const = 0;
virtual void UpdateAnimation(float timeStep) = 0;
virtual void OnRotate(DeviceOrientation newOrientation) = 0;
virtual ~IRenderingEngine() {}
};
I have an objective-c/c++ header file called GLView.h that looks like this:
#import "IRenderingEngine.hpp"
#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>
@interface GLView : UIView {
EAGLContext* m_context;
IRenderingEngine* m_renderingEngine; //Compiler error: Expected specifier-qualifier-list before "IRenderingEngine"
float m_timeStamp;
}
- (void) drawView: (CADisplayLink*) displayLink;
- (void) didRotate: (NSNotification*) notification;
@end
And finally, a GLView.mm file with a barebones implementation:
#import "GLView.h"
@implementation GLView
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
- (id)initWithFrame:(CGRect)frame {
return self;
}
- (void) drawView:(CADisplayLink *)displayLink
{
}
-(void) didRotate:(NSNotification *)notifi开发者_Python百科cation
{
}
@end
You need to rename HelloArrowAppDelegate.m to a .mm file. It states in the book on page 20 (middle section with the paws bullet point). I missed that section and had the same problem. After changing the file to .mm the program worked.
This error message e.g. occurs if one of your two headers gets included in a plain Objective-C source file, which doesn't know anything about handling C++ code.
To allow GLView
to be used from plain Objective-C sources, use only a forward declaration for the rendering engine and don't include the C++ header in GLView.h
:
// GLView.h:
struct IRenderingEngine;
@interface GLView : UIView {
struct IRenderingEngine* m_renderingEngine;
// ...
@end
// GLView.mm:
#import "IRenderingEngine.hpp"
// ... etc.
Alternatively you can use opaque pointers for wrapping C++ instances to keep the Objective-C interface more stable, see e.g. Rob Napiers post on the subject.
When this is fixed, you still need to fix the declaration for CreateRenderer1()
as others pointed out - either forward-declare struct IRenderingEngine;
before the function or just move it after the definition of the struct
.
I had the exact same problem. It turned out to be due to the fact that renaming HelloArrowAppDelegate.m to HelloArrowAppDelegate.mm in Xcode's Groups & Files did not actually rename the file! Once I used Finder to rename it the project compiled OK. Note Xcode may complain that the HelloArrowAppDelegate.m is missing when you open the project again, just right click it, delete it and then use "Add existing files" to add the HelloArrowAppDelegate.mm file back in.
This may seem a cop-out but I had exactly the same problem when I updated to XCode 4.x
I got around it by downloading the source code from O'reilly's website and just loaded the project. Xcode appeared to recognise it as an old project and configured itself accordingly; no compilation issues, worked first time. It's not the same as typing it in yourself but it works.
The line
struct IRenderingEngine* CreateRenderer1();
Must come after the declaration of the IRenderingEngine
class. (Also, if you intended to use the variable as a pointer to that structure type you should omit the parentheses in its declaration.)
For your other error I think you want to prepend the line with struct
.
I believe this line is causing the error:
struct IRenderingEngine* CreateRenderer1();
I'm not quite sure what you're trying to do there, but I think it should be removed entirely.
精彩评论