Compiling c code with root libraries

Hi all,

I have a pure c code which is build with a Makefile using the gcc compiler.
I would like to use the root classes so I am trying to compile the code together
with the root libraries.
My problem is that using e.g. CC = gcc I get all sort of errors regarding the root’s c++ code,
if I switch to CC=g++ then some of the c code has problems like:

test_grid.c:65: error: invalid conversion from void*' todouble*'
test_grid.c:70: error: invalid conversion from void*' tofloat*‘
test_grid.c:128: error: invalid conversion from void*' tofloat*’

(These lines correspond to “malloc” operations)

I understand that c and c++ are not the same thing, but what is the way around this?
How can one compile c code with the ROOT libraries?

Thanks

Hi,

[quote]My problem is that using e.g. CC = gcc I get all sort of errors regarding the root’s c++ code, [/quote]What kind of errors?

One possible issue that you must compile the C++ and the C files with 2 different compiler. I.e. in your makefile you need to define (and use) both CC=gcc and CXX=g++.

Otherwise you need to compile all your code in C++ and you will need to upgrade your C code a bit (for example replace double *myvar = malloc(…); with double *myvar = new double[…]; )

Cheers,
Philippe.

Hi,

Thanks for your answer!
I don’t see how I can use different compilers when I want to use the root classes
inside the c programs. I will try however the updating option. So you suggest that
in C++ there is no need to use malloc at all? Or one needs to cast the pointer
that malloc returns using the correct type (e.g. float* )? Is this why it brakes?

The errors I get are too many to post them but here are the first few lines.
I should also probably mention the following two points that

  1. I have not compiled root from source but I
    used the binary:
    AMD64 Linux for Redhat RHEL 4 (SLC4) and gcc 3.4, version 5.20/00
    and I am using an
    AMD Opteron™ Processor 146

  2. I am including the root .h files with this option in the Makefile:
    -I$(shell root-config --cflags)
    Is this sufficient?

So when using CC=gcc I get

In file included from /home/users/step0ut/root/include/Rtypes.h:30,
from /home/users/step0ut/root/include/TObject.h:31,
from /home/users/step0ut/root/include/TNamed.h:26,
from /home/users/step0ut/root/include/TDirectory.h:25,
from /home/users/step0ut/root/include/TROOT.h:29,
from gdecomp.h:5,
from read_basis.c:5:
/home/users/step0ut/root/include/Rtypeinfo.h:32:20: typeinfo: No such file or directory
In file included from /home/users/step0ut/root/include/Rtypes.h:30,
from /home/users/step0ut/root/include/TObject.h:31,
from /home/users/step0ut/root/include/TNamed.h:26,
from /home/users/step0ut/root/include/TDirectory.h:25,
from /home/users/step0ut/root/include/TROOT.h:29,
from gdecomp.h:5,
from read_basis.c:5:
/home/users/step0ut/root/include/Rtypeinfo.h:33: error: parse error before "std"
In file included from /home/users/step0ut/root/include/TObject.h:31,
from /home/users/step0ut/root/include/TNamed.h:26,
from /home/users/step0ut/root/include/TDirectory.h:25,
from /home/users/step0ut/root/include/TROOT.h:29,
from gdecomp.h:5,
from read_basis.c:5:
/home/users/step0ut/root/include/Rtypes.h:39: warning: type defaults to int' in declaration ofTClass’
/home/users/step0ut/root/include/Rtypes.h:39: warning: data definition has no type or storage class
/home/users/step0ut/root/include/Rtypes.h:40: error: parse error before “TBuffer”
/home/users/step0ut/root/include/Rtypes.h:40: warning: type defaults to int' in declaration ofTBuffer’
/home/users/step0ut/root/include/Rtypes.h:40: warning: data definition has no type or storage class
/home/users/step0ut/root/include/Rtypes.h:41: error: parse error before “TDirectory”
/home/users/step0ut/root/include/Rtypes.h:41: warning: type defaults to int' in declaration ofTDirectory’
/home/users/step0ut/root/include/Rtypes.h:41: warning: data definition has no type or storage class
/home/users/step0ut/root/include/Rtypes.h:42: error: parse error before “TMemberInspector”
/home/users/step0ut/root/include/Rtypes.h:42: warning: type defaults to int' in declaration ofTMemberInspector’
/home/users/step0ut/root/include/Rtypes.h:42: warning: data definition has no type or storage class
/home/users/step0ut/root/include/Rtypes.h:43: error: parse error before “TObject”

[quote]I don’t see how I can use different compilers when I want to use the root classes inside the c programs.[/quote]Sorry I missed that. Indeed you can NOT call C++ function/objects/etc. from a C compiled source.

[quote]I will try however the updating option. So you suggest that
in C++ there is no need to use malloc at all? Or one needs to cast the pointer that malloc returns using the correct type (e.g. float* )? Is this why it brakes? [/quote]Casting the return type of malloc will work, however I recommend that instead of malloc/free you use ptr =new …[] and delete [] ptr;

[quote]The errors I get are too many to post them but here are the first few lines. [/quote]Yes, they are just saying that the C compiler does not understand C++.

Cheers,
Philippe.

This is not quite true, you can call C++ functions from C, but they must be declared ‘extern “C”’ at compile time. (This is not the same as saying it is possible to use C++ objects within C, only that it is possible to call C++ functions from C (those can use C++ objects though))

e.g.

[code]// Test.cxx
#include
using namespace std;

extern "C"
void Test()
{
cout << “This is me, using a C++ feature” << endl;
}
[/code]

Then compile and link test.cxx with test.c

extern void Test(); int main( int argc, char *argv[] ) { Test(); return 0; }

[quote=“step0ut”]Hi all,

I have a pure c code which is build with a Makefile using the gcc compiler.
I would like to use the root classes so I am trying to compile the code together
with the root libraries.
My problem is that using e.g. CC = gcc I get all sort of errors regarding the root’s c++ code,
if I switch to CC=g++ then some of the c code has problems like:

test_grid.c:65: error: invalid conversion from void*' todouble*'
test_grid.c:70: error: invalid conversion from void*' tofloat*‘
test_grid.c:128: error: invalid conversion from void*' tofloat*’

(These lines correspond to “malloc” operations)

I understand that c and c++ are not the same thing, but what is the way around this?
How can one compile c code with the ROOT libraries?
[/quote]Can you upload your code? The simplest things to try is to change the extension of your source file from “.c” to ".cxx’ or “.cpp” and apply either “gcc” or “g++”. It may or may not resolve your issue. One needs to see your example to provide the concrete advice and eliminate the guess job. What about malloc. The function is available from C++ code as well as from C code. Your prooblem icomes from elsewhere. Show your example.
I would advice youi to try to apply ACliC too.
Assuming (Ehhhn, I have to guess) your C function looks like this

#include <stdlib.h> #include <stdio.h> void test_grid() { printf(" test_grid\n"); } you should be able to compile and execute it with ROOT as follows:

Hi,

The program compiled fine after replacing the malloc/free with new/delete and after
resolving some multiple definition linking errors in the headers files
for which the gcc compiler file did not complain before.
As we discussed with philippe casting the pointer that malloc returns would also
then make the code c++ compile-able.
My only problem now is that when including a root .h file I get the following run time error:
error while loading shared libraries: libCore.so: cannot open shared object file: No such file or directory

I guess that this could be related with my root installations which was not really an installation but just got the binary and set the $(ROOTSYS) in my path.
Could this cause the problem?

When I apply your last advise
(using root.exe -b test_grid.c++)
I get exactly the same complain:
root.exe: error while loading shared libraries: libCore.so: cannot open shared object file: No such file or directory

[quote=“step0ut”]if I switch to CC=g++ then some of the c code has problems like:

test_grid.c:65: error: invalid conversion from void*' todouble*'
test_grid.c:70: error: invalid conversion from void*' tofloat*‘
test_grid.c:128: error: invalid conversion from void*' tofloat*’

(These lines correspond to “malloc” operations)
[/quote]This is because your original code is not correct. I guess it contains something like this: float *x = malloc(100);
Your mistake is, the function malloc allocates 100 bytes of the memory and returns the “generic” pointer - void* as result. What you realy need is the pointer to the instance of the float… The “float* is not exactly the same thing as “void *”. However, the C compiler forgives this mistake. C++ wants you to confirm the code will do what you really want. To do that you need to add the explicit cast. Do

float *x = (float*)malloc(100); and your code is to be compiled properly with either compiler. it is less error prone to use float *x = (float*)malloc(25*sizeof(float)); instead.

Hi Valeri,

Thanks for your answer, yes as I said before both casting the pointer that malloc returns
or changing “malloc” to “new” solve the compilation problems. In the c code the return
pointer of malloc was indeed not casted.
How about the libCore.so issue? should I first try to configure and install root properly
or it should work with the binary as well?

[quote=“step0ut”]I said before both casting the pointer that malloc returns
or changing “malloc” to “new” solve the compilation problems[/quote]Switching from malloc to “new” please make sure you replace the free() with “delete []” as well. Again I have to guess. It would have been much simpler if you could upload your trouble code.

[quote=“step0ut”]root.exe: error while loading shared libraries: libCore.so: cannot open shared object file: No such file or directory [/quote]There is no evidence you need to re-build ROOT. The message in question means you have not set the correct environment variables yet. Please re-read root.cern.ch/root/Install.html. Pay your attention to the clause:

[quote]add $ROOTSYS/bin to PATH and $ROOTSYS/lib to LD_LIBRARY_PATH:
sh family:
export PATH=$ROOTSYS/bin:$PATH
export LD_LIBRARY_PATH=$ROOTSYS/lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=$ROOTSYS/lib:$DYLD_LIBRARY_PATH (MacOS X only)
csh family:
setenv PATH ${ROOTSYS}/bin:${PATH}
setenv LD_LIBRARY_PATH ${ROOTSYS}/lib:${LD_LIBRARY_PATH}
setenv DYLD_LIBRARY_PATH ${ROOTSYS}/lib:${DYLD_LIBRARY_PATH} (MacOS X only)
rehash

try running root:
all shells:
root[/quote]

Hi,

Ok thanks, the library path seems to have caused the problem to that.
Sorry for not posting the code, but is composed from quite a few files and it’s not
mine! I have already replaced free with delete []. Seems to compile fine and run
properly with root includes also.

:smiley: