开发者

c++ undefined reference to <a function>

开发者 https://www.devze.com 2023-03-04 18:16 出处:网络
HI, I have some questions about .h files and .cpp files in c++/linux(ubuntu). It is possible to compile a .h file using g++ or you can just compile a .cpp file that includes the .h file?

HI,

I have some questions about .h files and .cpp files in c++/linux(ubuntu).

  1. It is possible to compile a .h file using g++ or you can just compile a .cpp file that includes the .h file?

  2. From a .h file and it's .cpp file (.cpp where i include some code to the methods i've defines in .h file) I create a .so file using the command:

    g++-fPIC -shared my_code.cpp -o my_code.so`
    

    In the test.c开发者_StackOverflow中文版pp I include the .h file and using dlopen i create a handler over the .so file. Why do I have the following error:

    undefined reference to bool `Class::method(std::string)` `collect2: ld returned 1 exit status
    
  3. If I say virtual bool method... in the .h file there is no error when I compile test.cpp. Can someone explain what am I doing wrong? The thing is that i have a template. With templates I cannot use virtual..so..i have this undefined error and i don't know how to resolve it. THX

EDIT:

When i compile the my_code.cpp I have the errors:

/usr/bin/ld: .usr/lib/debug/usr/lib/crt1.o relocation 0 has invalid symbol index 12 (same with index 13,2,14...22 ).

But when i create the .so file there is no error . I use:

g++ test.coo -ldl -o test

for the test.cpp compilation.


Ad 1: It is possible to compile .h file (you can explicitly override the language detection), but you don't want to do it. The .h file is intended to be included and will not compile to anything useful on it's own.

Ad 2: You have to link against the library you created by passing the -lmy_code (but note that for that to work you have to create it as libmy_code.so) along with appropriate -L flag (directory where you placed libmy_code.so) to the linker. Like this:

g++ test.cpp -L. -lmy_code -ldl -o test

But you also have to change the first command to:

g++ -fPIC -shared my_code.cpp -o libmy_code.so
                                 ^^^
                                 libraries *must* have `lib` prefix on unix systems.

and this assumes both are done in the same directory—if not, you have to adjust the -L option to point to the directory where libmy_code.so is. Also you have to place libmy_code.so somewhere where the dynamic linker can find it. Either by installing it or by setting environment variable LD_LIBRARY_PATH to appropriate directory. Alternatively you can compile by using

g++ test.cpp my_code.so -ldl -o test

This does not force the lib prefix and it creates an "rpath" entry in the binary so it will find the library in the original place.

This all assumes you want to use it as regular library in which case you don't want to use dlopen. dlopen is for opening libraries as plugins at runtime and than they can only be accessed by fetching pointers to symbols using dlsym(), but if you want to access the library normally, you have to link against it so the linker can resolve the symbols.

If instead you wanted to use dlopen, you must not include my_code.h in test.cpp and must not use anything it defines except by getting the symbols with dlsym. And since this is C++, it in turn requires you understand the symbol mangling scheme, because dlsym will not do this for you.


  1. Generally there is no need to compiling a .h file, it simply generates a huge file with .gch extension I guess.

  2. The error you are getting is a link time. While creating the .so file, you do not actually link the code. So all undefined symbol are assumed to be present at some place. When you link it, the linker will find for those symbols. So, you should compile/link all the .cpp file together. The error will go away.

Also, For templates, the definition of the code must always be visible. So wherever you write the templated function/variable definition, include that file everywhere.

Edit: You can have virtual method with template classes; but you can not have virtual template methods.

template<typename T>
class A {
  virtual void foo(int); // ok
};

class A {
  template<typename T>
  virtual void foo(T); // illegal
};
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号