0

In Visual Studio 2022, for Project A I want to set up Project B that references the header (.h) and source (.cpp) files of Project A (reusing existing code). However, I don't know how the point to the existing files correctly in order for Project B to build successfully. Using #include "../unittest.h" and setting the path in Settings->C/C++->Additional Include Directories did not work (Error LNK2019, Error LNK1120). The project is a console application project.

The contents of the referencing files looks like this:

unittest.h (Project A)

#pragma once

int ret1(void);

unittest.cpp (Project A)

#include "unittest.h"

int ret1(void)
{
  return 1;
}

main.c (Project B)

#include <stdio.h>
#include "../unittest.h" // -> This doesn't seem to be enough

int main()
{
    char temp[10];
    sprintf(temp, "%d", ret1()); // Here I want to use the external function

    printf(temp);
}

Any help on how to include the external files is appreciated.


Build Logs:

Rebuild started...
1>------ Rebuild All started: Project: TestProject, Configuration: Debug x64 ------
1>TestProject.cpp
1>TestProject.obj : error LNK2019: unresolved external symbol "int __cdecl ret1(void)" (?ret1@@YAHXZ) referenced in function main
1>C:\Users\dirtl\Documents\Visual Studio 2022\Projects\TestProject\x64\Debug\TestProject.exe : fatal error LNK1120: 1 unresolved externals
1>C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Microsoft\VC\v170\Microsoft.CppCommon.targets(1094,5): error MSB6006: "link.exe" exited with code 1120.
1>Done building project "TestProject.vcxproj" -- FAILED.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
CodeSocke
  • 91
  • 1
  • 7
  • 1
    Why can't you add all source files to the project in your IDE and then let the IDE worry about paths? – Lundin Nov 07 '22 at 09:26
  • That would be one possibility. However, in order not to implement changes twice I do not want to duplicate the `.h` and `.cpp` files. – CodeSocke Nov 07 '22 at 09:37
  • 1
    Because setting `Additional Include Directories` resulted in a **link error** not a compile error, that means that it did work, your code compiled and the header file was found as expected. Now you need to work to the additional steps required to resolve the link error. Possibly you just need to include unittest.cpp in project B. – john Nov 07 '22 at 09:44
  • Please [edit] your question to include a full and complete copy-paste of your build-log. – Some programmer dude Nov 07 '22 at 09:47
  • Also, in "Project B", you are linking to the `unittest.cpp` source file from "Project A"? Or if "Project A" is a library, do you link with that library? – Some programmer dude Nov 07 '22 at 09:49
  • @john That sounds like a step in the right direction, thanks! I added `#include "../unittest.cpp"`, cleaned *C/C++->Additional Include Directories* and added the folder of *Project B* to *Linker->Additional Libraries* and it compiled successfully. **Great!** Nevertheless, I thought including just the header file is enough as long as the source file has the identical name and is located in the same directory. – CodeSocke Nov 07 '22 at 09:51
  • This might be a good time to learn about the concept of [*translation units*](https://en.wikipedia.org/wiki/Translation_unit_(programming)), which is the unit that the compiler will use. A translation unit (abbreviated as TU) is basically a single source file with all included header files. The compiler usually builds this into an object file, and the object file is linked with other object files and libraries to form the actual executable program file. A few standard and system libraries are linked automatically, but nothing else. – Some programmer dude Nov 07 '22 at 09:54
  • 3
    @CodeSocke No you really are confused. Never `#include` .cpp files. When I said include the file, I meant **add it to your project B**, not use `#include`. Right click on your project in the solution explorer and pick Add/Existing Item – john Nov 07 '22 at 09:54
  • @CodeSocke You said *as long as the source file has the identical name and is located in the same directory*, That's completely incorrect. – john Nov 07 '22 at 09:57
  • @john I understand now as I have never seen this before. I added the `.cpp` file as an existing item to my project and there's no link error. Thanks for sharing your knowledge on the connections of the several files behind the code. – CodeSocke Nov 07 '22 at 10:06
  • @CodeSocke Glad to help. Going from programs with a single source file to multiple source files is a very common issue for beginners. – john Nov 07 '22 at 10:11

1 Answers1

1

To allow for function overloading, C++ compilers uses name mangling.

That means the actual name of a C++ function is not quite what's expected, as it also have information about arguments etc.

To make a C++ function callable from C (or other compatible languages) the C++ function must be declared as extern "C":

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

int ret1(void);

#ifdef __cplusplus
}
#endif

If you modify the header file as above, and make sure that it's included in the C++ source file, then the function will not have a mangled name, and it can be called from C.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks, I appreciate the quick response! Unfortunately the errors still persist after implementing your suggestion. It seems that the source file can't be referenced for some reason. Is the way of including the file by using `#include "../unittest.h"` correct? – CodeSocke Nov 07 '22 at 09:43
  • 1
    @CodeSocke You seem a little confused about the nature of C++ errors. If you are receiving linker errors then this has nothing at all to do with `#include`. In fact it proves that the includes are working. Only compiler errors might mean that the includes are not working. – john Nov 07 '22 at 09:47
  • @CodeSocke As for the question about `#include "../unittest.h"` that might or might not be correct. It depends on the relative locations of your files, and the project settings that you have. So no easy answer to that question. – john Nov 07 '22 at 09:49
  • @CodeSocke A simple test for you. Add this `#error "can you see this?"` to your unittest.h file. Now try to compile. If you see an error message the quotes the string above, then that proves that the include is working, and that your problems are linker problems not include problems,. – john Nov 07 '22 at 09:53
  • @john When adding `#error "can you see this?` it shows up in the build logs. Nice way of confirming. – CodeSocke Nov 07 '22 at 10:09