Linking C from C++ in OS X Mavericks

后端 未结 3 1122
温柔的废话
温柔的废话 2021-01-04 17:51

Having transitioned to OS X Mavericks and XCode 5.0.1, I can no longer gracefully link compiled C files (output from gcc) to a C++ project (output from g++).

The off

相关标签:
3条回答
  • 2021-01-04 18:43

    Adding a "-x c" (without quotes) before "vec.c" should fix it.

    If you compile multiple .c/.cpp files in the same line you can use "-x c" or "-x c++" before each list of C or C++ filenames to switch context appropriately. For example:

    g++ -x c  alpha.c beta.c  -x c++  gamma.cpp
    
    0 讨论(0)
  • 2021-01-04 18:49

    Here's an example Makefile that let us use C++ code/function in a C program.

    CC=clang
    CXX=clang++
    CFLAGS=-Wall -g
    CXXFLAGS=-Wall -g -std=c++11 -I.
    
    DEPS=CPP.h
    OBJ=main.o CPP.o
    
    RM=rm -f
    
    # compile only, C source
    %.o: %.c
        $(CC) -c -o $@ $< $(CFLAGS)
    
    # compile only, C++ source
    %.o: %.cpp $(DEPS)
        $(CXX) -c -o $@ $< $(CXXFLAGS)
    
    # link
    main: $(OBJ)
        $(CXX) -o $@ $^ $(CXXFLAGS)
    
    clean:
        $(RM) $(OBJ)
    

    As you can see, we generate our objects separately using CXXFLAGS and CFLAGS in two separate calls to the compiler. In the context of Mac using Xcode's clang, clang (CC) and clang++ (CXX) are actually the same thing. Only the differing flags matter. I am just being pedantic by stating the definitions of CC and CXX in the above example Makefile.

    Once the object files are generated, we are good to go to link them together.

    Note however that you have to do one extra step to make your C++ code usable by the C program.

    In CPP.h in this example, you have to explicitly use extern "C" to specify linkage for your C++ code for use by C.

    For example, like this:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    double timesTwo(double number);
    
    #ifdef __cplusplus
    }
    #endif
    

    The preprocessor macros #ifdef __cplusplus and #endif are to make sure that our header file won't cause C-mode compilation errors and is only in-effect during C++-mode compilation.

    This complete example comprises only 4 files.

    • Makefile
    • main.c
    • CPP.h
    • CPP.cpp

    The Makefile source and CPP.h are explained above.

    For a complete understanding, I am including main.c and CPP.cpp here as well.

    main.c:

    #include <stdio.h>
    #include "CPP.h"
    
    int main()
    {
        printf("Running main.c\n");
        double ans = timesTwo(3.0);
        printf("The answer from our C++ timesTwo function, when given 3.0, is %f\n", ans);
    
        return 0;
    }
    

    CPP.cpp:

    #include "CPP.h"
    
    double timesTwo(double number)
    {
        return 2 * number;
    }
    

    I trust that this explanation and example clarifies how we can set up our Makefile, specify the #ifdef __cplusplus preprocessor macro and extern "C" linkage declaration to allow C++-to-C interop, and with no erroneous clang warning when we run make.

    0 讨论(0)
  • 2021-01-04 18:52

    Most probably you are a victim of Name mangling. To avoid name mangling in C++, use extern "C" around declarations, like:

    #ifdef __cplusplus 
    extern "C" {
    #endif
        void load_dmat(char const*);
    #ifdef __cplusplus
    }
    #endif
    
    0 讨论(0)
提交回复
热议问题