Keep on getting LNK2019 error when mixing C and C++ - c++

I'm trying to call C code from C++. I have 3 files: pubsub.cpp, pubsublib.c & pubsublib.h.
I know I have to use extern "C" in order to call a C function from C++.
I've literally tried everything, but I am still getting the following LNK2019 unresolved external symbol error:
LNK2019 unresolved external symbol _thisIsATestFunction referenced in
function _main
pubsublib.c
#include "pubsublib.h"
void thisIsATestFunction()
{
// do something
}
pubsublib.h
#ifndef pubsublib_H
#define pubsublib_H
void thisIsATestFunction();
#endif
pubsub.cpp
#include <string>
#include <iostream>
#ifdef __cplusplus
extern "C"{
#endif
#include "pubsublib.h"
#ifdef __cplusplus
}
#endif
using namespace std;
int main() {
thisIsATestFunction();
return 0;
}
I have also tried to just include the functions but I'm getting the same error. I'm really lost at the moment and have searched a lot... Any help would be greatly appreciated.

It works perfectly fine when you actually link with the necessary file.
When you compile pubsub.cpp you have to add pubsublib.obj to the command line. For example, this solved the problem for me using Visual Studio 2015:
cl -c pubsublib.c
cl pubsub.cpp pubsublib.obj
If you're building with the IDE, you simply need to make sure that pubsublib.c is a dependency and pubsublib.obj is specified as input to the link step.

You have to add a reference to the library in your application.
If you have both projects in one solution in Visual C++ 2015 you
right click your application project
select "Add..." from the drop down menu
select "Reference" from the menu
check you library in the list
If you have each project in its own solution you
right click you application project
select "Properties"
open "Linker" section "Input" page
add your .lib file to the "additional dependencies"
Your application should compile without LNK2019 after doing so.
There are also "build dependencies" to manage, but these do not affect the libraries linked to your project (only the build order).
(I am using a german edition of Visual Studio so please fix the translations if some of them are wrong)

Your declaration works fine, as proves the error message (_thisIsATestFunction is indeed a C-undecorated name).
Now two possibilities remain
the file pubsublib.c was not compiled as C, causing the compiled function to get decorated;
the file pubsublib.c was compiled as C, but didn't take part to the linking.
Only your solution/project(s) file can tell the truth. Can we see a screen copy of the Solution Explorer ?

This linkage error is produced when "pubsublib.c" file is compiled as C++ file (in g++). Please change your project options so that all .cpp files are compiled with g++, and all .c files are compiled with gcc.
After changing settings make sure that "pubsublib.c" file is really compiled with gcc. It can be found in compilation output like following:
g++.exe -c main.cpp -o main.o
gcc.exe -c pubsublib.c -o pubsublib.o
g++.exe main.o pubsublib.o -o Project1.exe

Related

C++ library in Visual Studio Code

I have made a c++ project in CodeBlocks. Now I started using Visual Studio Code and I can't figure out how to connect files. I have main.cpp with my main code, then I have sortlib.cpp with some sorting functions and I have sortlib.h. My question is how do I connect these files, so I can #include "sortlib.h" in my main.cpp file and use the functions.
I have tried including sortlib.h in my sortlib.cpp program and then my sortlib.h in my main.cpp program, but it didn't work.
I'm on windows so I just compiled my sortlib.cpp program by typing g++ sortlib.cpp and it showed me this error message
c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../libmingw32.a(main.o):(.text.startup+0xc0): undefined reference to 'WinMain#16'
Minimal code structure
main.cpp
// Other header files
#include "sortlib.h"
int main(void) {
...
}
sortlib.h
void someFunction();
...
sortlib.cpp
// Include headers that are required
void someFunction() {
...
}
The minimal required command
g++ -g main.cpp sortlib.cpp
There is no such thing as "connecting" files in programming. You have to make sure that your compiler is compiling all the .cpp files into .o/.obj files and that they are all getting linked together to produce your final executable.

My Class.cpp is not being seen by the linker

I am trying to write a C++ class in a separate header and cpp file using VS Code as my IDE with the 'run' and 'C++' extensions.
main.cpp
#include "Fan.h"
int main() {
Fan fan1;
return 0;
}
Fan.h
#ifndef FAN_H
#define FAN_H
class Fan {
public:
Fan();
};
#endif
Fan.cpp
#include "Fan.h"
#include <iostream>
using namespace std;
Fan::Fan() {
cout << "Fan Class" << endl;
}
I really can't seem to find anything popping out as obviously wrong. I am wondering if it is a setup problem with VS Code.
If I change #include "Fan.h" in main.cpp to "Fan.cpp" it works so it makes me think that the code works but that the linker is not setup right.
Would appreciate any help!
EDIT: Ok so I've tried the code in a different IDE and it worked. It's something to do with VS Code. Here is the error:
[Running] cd "c:\Users\<USER>\Desktop\Fan\" && g++ tempCodeRunnerFile.cpp -o tempCodeRunnerFile && "c:\Users\<USER>\Desktop\Fan\"tempCodeRunnerFile
C:\Users\<USER>\AppData\Local\Temp\cclMFKxO.o:tempCodeRunnerFile.cpp:(.text+0x57): undefined reference to `Fan::Fan()'
collect2.exe: error: ld returned 1 exit status
It sounds like the IDE is only compiling main.cpp. You need to find the command that is compiling main.cpp and ensure that it also compiles fan.cpp into fan.obj. You will also need to ensure that both main.obj and fan.obj are passed to the linker (which produces the executable program, main.exe or whatever).
There are two steps involved here:
cpp -> obj (compiling each source file into a matching object file)
obj -> exe (linking many object files into an executable)
I would say to make a CMakeLists.txt file and add main.cpp and fan.cpp into the add_executable section. Then VS can handle and run files through CMake.

Contradictory unresolved external symbol + unused library altogether with VS2017 and FFMPEG 4

I'm having a small c++ project in Windows with FFmpeg 4.0.2. However, I have weird problem: I'm compiling in x64, having x64 libraries, and having correct link input, but I got the LNK2019 error AND at the same time "unused libraries" in the linker output /VERBOSE:
1>Unused libraries:
1> I:\lib\ffmpeg-4.0.2-win64\lib\\avcodec.lib
1> I:\lib\ffmpeg-4.0.2-win64\lib\\avutil.lib
I checked manually that lib files are x64. I:\lib\ffmpeg-4.0.2-win64\lib\ is in the LIBPATH.
Same symptoms with ICC.
How could this happen ?
To include the headers of ffmpeg in a C++ program you have to take in account that ffmpeg uses the C calling conventions. Otherwise your linker will expect C++ name mangling on the function names. However, since ffmpeg is straight C, you'll have to tell you compiler this.
For example if you include avformat.h in your program do it as follows.
#ifdef __cplusplus
extern "C" {
#endif
#include <avformat.h>
#include <avcodec.h>
#include <avutil.h>
#ifdef __cplusplus
}
#endif
The same goes for the other ffmpeg headers.

Having trouble embedding Lua for Windows install into C++ program

This is the first question I have found myself not being able to get to the bottom of using my normal googling/stack overflowing/youtubing routine.
I am trying to compile a minimal Lua program inside of a C++ environment just to ensure my environment is ready to development. The Lua language will be later used for User Interface programming for my C++ game.
First some basic information on my environment:
Windows 7 64-bit
Visual studio 2010
Lua for Windows 5.1 (latest build I could download from google code)
Here is the code I am trying to compile:
// UserInt.cpp : Defines the entry point for the console application.
//
#pragma comment(lib,"lua5.1.dll")
#include "stdafx.h"
#ifndef __LUA_INC_H__
#define __LUA_INC_H__
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
int _tmain(int argc, _TCHAR* argv[])
{
lua_State * ls = luaL_newstate();
return 0;
}
#endif // __LUA_INC_H__
Here is the Error I am getting:
1>UserInt.obj : error LNK2019: unresolved external symbol _luaL_newstate referenced in function _wmain
1>c:\users\deank\documents\visual studio 2010\Projects\UserInt\Debug\UserInt.exe : fatal error LNK1120: 1 unresolved externals
Things I have tried:
I have read about lua_open()(and several other functions) no longer being used so I tried the newstate function instead. I get the same error. This was more of a sanity check than anything. I am using 5.1 and not 5.2 so I do not think this really matters.
I have also read this thread Cannot link a minimal Lua program but it does not seem to help me because I am not running the same environment as that OP. I am on a simple windows 7 and visual studio environment.
The top pragma comment line was something I saw in yet another thread. I get the same error with or without it.
I have gone into my visual studio C++ directories area and added the lua include to the includes and the lua lib to the libraries.
So it seems like my program is seeing the .h and seeing the symbol. But for some reason it is not getting the .cpp implementation for the functions. This is why I was hoping including that .dll directly would help fix the problem, but it hasn't.
So, I feel like I have exhausted all of my options solving this on my own. I hope someone is able to help me move forward here. Lua looks like an awesome language to script in and I would like to get my environment squared away for development.
I hope it is just some silly error on my part. I believe I have provided as much information as I can. If you need more specifics I will update with info if I can provide it.
Edit1
Tried the solution in this Can't build lua a project with lua in VS2010, library issue suspected
That did not work either.
You'll need to have the library (.LIB) file and add that to VS. Use Project > Properties and go to Linker > Input and add the full .lib filename to the "Additional Dependencies" line. Note that the .LIB is different from the .DLL.
Personally, I prefer adding the source code to my project, over referencing the dynamic link library. The following procedure will let you do as such.
Download the source code ( http://www.lua.org/ftp/ ), uncompress it.
In Visual Studio, choose File > New > Project and choose Visual C++, Win32, "Win32 Console Application".
In your project in Visual Studio, add all the source code, except luac.c. Also delete the main() function out of the file that VS created for you. This is usually given the name of the project you specified with the .cpp file extension. You could just remove this file all-together from the project.
Build and Run.
This is the Lua console

Creating static library and linking to it with premake

I am currently trying to learn how to use premake 4 in order to apply it to the OpenGL sdk. I am currently trying to make a Visual Studio 2010 solution that constructs 2 projects, one being a static library, the other contains a single main source file, with the main method.
This project is extremely simple, and is solely for the purpose of learning premake. In the static library project, named Test, I have 2 files, Test.h and Test.cpp. Test.h contains the prototype for the method print(). print() simply prints a line to the console. Using premake, I linked the static library to the Main project, and in main.cpp I have included the Test.h file. My problem is this: in VS2010 I get this error when I attempt to build:
1>main.obj : error LNK2019: unresolved external symbol "void __cdecl print(void)" (? print##YAXXZ) referenced in function _main
1>.\Main.exe : fatal error LNK1120: 1 unresolved externals
Here is my code in the 4 files, the premake4.lua:
solution "HelloWorld"
configurations {"Debug", "Release"}
project "Main"
kind "ConsoleApp"
language "C++"
files{
"main.cpp"
}
configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }
links {"Test"}
project "Test"
kind "StaticLib"
language "C++"
files{
"test.h",
"test.cpp"
}
Test.cpp:
#include <iostream>
void print(){
std::cout << "HELLO" << std::endl;
}
Test.h:
void print();
Main.cpp:
#include <conio.h>
#include "test.h"
int main(){
print();
getch();
return 0;
}
If you are wondering why there is a getch() there, on my computer the console immediately closes once it reaches return 0, so I use getch() to combat that issue, which forces the window to wait until the user has pressed another key. Any advice on this issue would be wonderful, because I simply am not sure what the problem is. If it is something simple please dont castrate me on it, I have very little experience with premake and static libraries, which is why I am trying to learn them.
links {"Test"}
Lua is not Python. Whitespace is irrelevant to Lua, just like whitespace doesn't matter to C++. So your links statement only applies to the "Release" configuration. If you want it to apply to the project as a whole, it needs to go before the configuration statement, just like your kind, files, and other commands.
Premake4 works this way so that you could have certain libraries that are only used in a "Release" build (or Debug or whatever). Indeed, you can put almost any project command under a configuration. So you can have specific files that are used only in a debug build, or whatever.