-1

I have a C++ source mycpp.cpp and a C source myc.c. The C source contains a function myCFunc(), which is called from the C++:

extern "C"
{
#include "my_c.h"
}

void aCppFunction()
{
    myCFunc(stuff, and, things);
    ...
}

The two sources are compiled (to .o), and then archived (to .a), and then indexed, so no linking occurs:

ar qc thing.a *.o
ranlib thing.a

Later in the wider software build, this component archive is linked into a binary, and I get this error:

/usr/bin/ld: /path/to/mycpp.cpp:55: undefined reference to `myCFunc(unsigned char const*, unsigned int, unsigned int)'

I have extracted thing.a and can quite clearly see myc.c.o and mycpp.cpp.o, so I search them for the function:

> nm myc.c.o | grep myCFunc
00000000000001d0 T myCFunc
> nm -C mycpp.cpp.o | grep myCFunc
                 U myCFunc(unsigned char const*, unsigned int, unsigned int)

Can you see what is happening here? Why does the nm result for the C++ include the list of argument types, but the C result not? It seems to me that the function myCFunc() is defined in myc.c.o, which is part of thing.a along with mycpp.cpp.o, and that myCFunc's header is included correctly.

Please help!

Walkingbeard
  • 590
  • 5
  • 15
  • 4
    Clearly, the caller of `myCFunc` does not see that name as `extern "C"`, because the error message contains the parameter types. If it were seen as `extern "C"`, the error message would only say `undefined reference to myCFunc`. – j6t May 25 '22 at 15:21
  • Thank you! I am not a C++ guy, and that is a tremendous help. – Walkingbeard May 25 '22 at 15:27

1 Answers1

0

The unlikely answer, based on j6t's invaluable comment:

Clearly, the caller of myCFunc does not see that name as extern "C", because the error message contains the parameter types. If it were seen as extern "C", the error message would only say undefined reference to myCFunc. – j6t

... is that what I did not show above, due to my C++ inexperience, is that the C header was included at the end of a train of other C++ headers, without using extern "C".

Walkingbeard
  • 590
  • 5
  • 15
  • 2
    Since everything is under your control, the conventional way to avoid such issues would be to put the `extern "C"` declaration into the header, with appropriate condition-compilation guards, so that both C and C++ clients can just `#include` it. – John Bollinger May 25 '22 at 15:54