0

What I am trying to do is call a C++ method from within a C file, in a new-to-me-but-fairly-large codebase. I have cribbed an implementation from elsewhere in the codebase, but am getting linker errors when I try to build it.

What I think I am doing is making a class in a .cpp/.h file pair. In a global header file, I declare a wrapper function, and in the .cpp file I define that wrapper function within extern "C" and have it call one of the class' methods. Then I call the wrapper function from my main .c file.

What I am actually doing is something wrong. I've spent the last few hours reading around on similar stackoverflow errors and how extern "C" works, but I still don't understand what isn't going right. Is there an obvious mistake in what I'm doing here?

I am not confident in my understanding of how the build system for this project is set up, but I generally trust that it's set up correctly, and that I've added myclass.cpp to the correct list of build targets. So I'm thinking the error is probably somewhere below.

Error message:

Creating objlist.lnk...
Linking into output.elf

module.o: In function `MyClass::MyMethod()':
~/myclass.cpp:5: undefined reference to `MyClass::stat_MyClass'
~/myclass.cpp:5: undefined reference to `MyClass::stat_MyClass'
module.o:~/myclass.cpp:5: more undefined references to `MyClass::stat_MyClass' follow
collect2: error: ld returned 1 exit status
make[1]: *** [output.elf] Error 1
make: *** [default] Error 2

Paraphrased code:

global.h

#ifdef __cplusplus
extern "C" {
#endif
  int my_c_wrapper_func(void);
  // other function declarations
#ifdef __cplusplus
}
#endif

global.c

#include "global.h"
// my_c_wrapper_func() not defined here
// other function definitions

myclass.h

#include "global.h"
class MyClass {
public:
  static MyClass* get() { return &stat_MyClass; } // Get the singleton
  int MyMethod();

private:
  static MyClass stat_MyClass; // The singleton
}

myclass.cpp

#include "myclass.h"

extern "C" int my_c_wrapper_func() {
  return MyClass::get()->MyMethod();
}

int MyClass::MyMethod() {
  return 1;
}

main.c

#include "global.h"
int main() {
  return(my_c_wrapper_func());
}
Scott
  • 504
  • 6
  • 17
  • 1
    `static MyClass stat_MyClass` is a declaration of a static variable. You also need a definition. – HolyBlackCat Dec 18 '19 at 23:34
  • 2
    Does this answer your question? [Initialize static variables in C++ class?](https://stackoverflow.com/questions/5019856/initialize-static-variables-in-c-class) Or [this one](https://stackoverflow.com/q/9282354/1270789)? – Ken Y-N Dec 18 '19 at 23:35
  • 1
    @HolyBlackCat you're completely right, that was my stupid error. Adding "MyClass MyClass::stat_MyClass" to the top of my .cpp file fixed everything. The error didn't show up when I was just compiling the file so I didn't think to focus my efforts on stuff that was (or wasn't) there before I added in the extern code. Thank you! – Scott Dec 18 '19 at 23:43

1 Answers1

3

@HolyBlackCat was right, my error was that I had forgotten to define stat_MyClass. Adding the following line to the top of myclass.cpp fixed everything.

MyClass MyClass::stat_MyClass;

The error didn't show up when I was just compiling the standalone file so I didn't think to focus my efforts on stuff that was (or wasn't) there before I added in the extern code. Thank you!

Scott
  • 504
  • 6
  • 17