9

I have two projects; static library and tests.

I am sure that I configured Visual Studio correctly to "tests" project use static library. Here is what I did:

  1. Configured library project to build as static library .lib
  2. Added additional include directories in tests (C/C++ -> General -> Additional include directories)
  3. Added additional library directories in tests (Linker -> General-> Additional library directories)
  4. Added my library as dependency (Linker -> Input-> Additional dependencies)

I can see that my "tests" project see the .lib file and seems to "try" to link to it. I noticed that when I use objects (defined in classes) in my tests project, everthing is fine. Problem is when I try to use functions (not member functions!).

Example:

In my header (.h) file:

/*includes omitted*/

namespace kx
{
   void func();
   /*...and more API functions*/
}

In my source file (.cpp)

#include "../MyHeader.h"

namespace kx
{
    void func()
    {
        /*definition...*/
    }

    /*and more definitions...*/
}

Will result in linker error; unresolved external symbol "void __cdecl kx::func()"

I read somewhere that this is caused by mixing C with C++ code, and solution to this is to use extern "C" in function declarations. I tried that and it solved my problem, but It seems unclear to me, since I use only c++.

Additionally, If I understand the mechanism right, when I use extern "C" my namespaces will be ignored, which is exactly what I dont want in this design.

Next, I thought that maybe __cdecl causes this problem, so I changed my function declarations to void __stdcall func(), but I had exactly the same linker error unresolved external symbol "void __cdecl kx::func()"

I work as C++ programmer and when I asked senior stuff about my problem, they told me that design described above should work without extern C, unless I dont mix it with C code.

I would like to know if there is something wrong with my setup/approach/design. In the end I can live with extern C approach, but I would be very surprised if this is the only solution.

I use visual studio 2017.

DannyX
  • 395
  • 1
  • 5
  • 11
  • 2
    `extern "C"` controls wether C++ name mangling is applied. (With `extern "C"` it is *not*.) As C++ supports polymorphy, the linker would have problems with multiple functions with same name. Hence the C++ compiler "decorates" the function names (in definition as well as in calls). If you want to use C functions you have to disable decoration to prevent link errors. – Scheff's Cat Oct 28 '17 at 07:14
  • 2
    We use `extern "C"` for C++ functions as well if we want to use them in plug-ins. Name-mangling is implementation-dependent. If you want to link at run-time i.e. search a function pointer by string, `extern "C"` is useful. Otherwise, we had to search the decorated name but (due to implementation dependent name-mangling) its difficult to determine. – Scheff's Cat Oct 28 '17 at 07:17
  • 3
    Btw. `extern "C"` and C++ namespace? Hmm. Found this in google: [SO: extern “C” linkage inside C++ namespace?](https://stackoverflow.com/q/28996944/7478597) – Scheff's Cat Oct 28 '17 at 07:21
  • This link may be helpful https://stackoverflow.com/questions/19886397/how-to-solve-the-error-lnk2019-unresolved-external-symbol-function – Matteo Ugolotti Jan 10 '19 at 11:23
  • Also this link could be interesting https://thinkingeek.com/2012/08/08/common-linking-issues-c/ , I'm not really sure it makes sense, but is it possible that visual studio is treating your header as a C header due to the .h extension ? In that case the funciton name will not match the decorated function name generated for the .cpp file. Can you try replacing the .h with a .hpp ? – Matteo Ugolotti Jan 10 '19 at 11:32

0 Answers0