I could have put this in my previous post, but I do think that it is a seperate question… I have created a basic Cocoa program from the template offered in XCode 3.2. I then changed the main.m file to a main.mm file and I added a new C++ class that I wrote called TestClass. I compiled that and it ran fine. I then wanted to take this a step further and use some of the root API inside of the TestClass class. This is where things got bad… When I tried to build I got a bouch of errors that look like:
/usr/local/root/include/TString.h:392:0 /usr/local/root/include/TString.h:392: error: cannot convert 'objc_class*' to 'TClass*' in return
These are happeneing at the following lines:
ClassDef(TString,1) //Basic string class
This is happening for all of the ClassDef style statements in the root API, so right now I have 18 errors because I tried to include TFile.h.
Thanks for any help. I really want to get this going. Untitled2.tar.gz (22.7 KB)
could you look at the C pre-processor output. It looks that there is a define in the Objc/Cocoa headers that change something in the ROOT code. Typically use g++ -E etc. Please let me know.
Well, I generated the cpp output of the main.mm file. I did it with the following line:
gcc -E main.mm `root-config --cflags`
The output is rather large and I looked through it but I was unsure what I was looking for. I am attaching it to this email so that you can take a gander at it and see what you were looking for.
after some analysis it looks like an ObjC++ compiler error. For example, this little class reproduces the problem, myclass.mm:
#include <stdio.h>
class MyClass {
private:
int fInt;
public:
MyClass() { fInt = 10; }
virtual ~MyClass() { }
static int Class() { return 9; }
};
int main()
{
MyClass m;
printf("%d\n", MyClass::Class());
return 0;
}
compiling it using:
/Developer/usr/bin/g++-4.2 -c myclass.mm
Gives the error:
class.mm: In function 'int main()':
class.mm:16: warning: format '%d' expects type 'int', but argument 2 has type 'objc_class*'
rename the file to myclass.cxx and use the same compile command it will compile fine. Change in myclass.mm the two instances of Class() to Class1() and it will also compile fine.
It seems strange to me that just changing the name of the method to have a number in it makes the difference. I would imagine that I could download and install the latest gcc compiler and that might fix the issue…
Clearly GNU objc++ does something special with the Class token. I don’t see how to work around it. What you could do is try to separate ROOT from the Cocoa GUI. In the GUI you call the ROOT code via some C interface.
[quote=“rdm”]Clearly GNU objc++ does something special with the Class token. I don’t see how to work around it. What you could do is try to separate ROOT from the Cocoa GUI. In the GUI you call the ROOT code via some C interface.
Cheers, Fons.[/quote]
Actually, this bug is quite nasty and annoying. To work around it, now I have to include UGLY wrappers, something like this
//ROOT's class, contains ClassDef macro.
#include "Rtypes.h"
class Name : public TObject {
public:
void fun();
private:
ClassDef(Name, 0);
};
And my wrapper C++ class to be used from Objective C++:
//My objective-C++ header, to be included into Obj-C source files.
class Name; //only forward declaration, header can not be included here.
class NameWrapper {
public:
void fun(); //will call ptr->fun() in NameWrapper.cxx, which CAN include header.
private:
Name *ptr;
};
This means, that I have to repeat ALL required interfaces TWICE and to use ugly memory management - create wrapper and in a wrapper create real object.
I suggest, to fix this strange limitation we must modify ClassDef macro. Instead of name::Class() I propose this->Class(). This does not change the meaning of the program, since ‘Class’ is a static member-function and the static type of ‘this’ is known and this type will be used in name lookup for ‘Class’; so, it will be the synonym of ‘name::Class()’ and is a legal C++ code.
I do not know, what clang (?) is doing with ‘Class’ identifier, but this helps.
Another problem is TBuffer.h, it contains operator << with call TObject::Class, it can be replaced (again) with syntax like obj->Class(), which is still ok, since calls required static member-function and is synonym to TObject::Class.
I’ve verified with Apple and this bug is only there when using g++. As we only use clang in the ROOT iOS port there should be no issue.
Cheers, Fons.[/quote]
Hi Fons,
I’ve just (before you answered:)) noticed, that you root1 project can be compiled without any problems and modification, and just checked - I had llvm GCC as compiler in my project, now I switched to clang llvm and do not need modifications in Rtypes.h.