Linking error while using static library linkage - c++

This might have been asked previously, however, I found it only in context of Classes, and this is not the case.
Utils.h
#ifndef _UTILS_H_
#define _UTILS_H_
#include <cmath>
//is 'x' prime?
bool isPrime(long long int x);
//find the number of divisors of 'x' (including 1 and x)
int numOfDivisors(long long int x);
#endif //_UTILS_H_
Utils.cpp
#include "Utils.h"
bool isPrime(long long int x){
if (x < 2){
return false;
}
long double rootOfX = sqrt( x );
long long int flooredRoot = (long long int)floor ( rootOfX );
for (long long int i = 2; i <= flooredRoot; i++){
if (x % i == 0){
return false;
}
}
return true;
}
int numOfDivisors(long long int x){
if (x == 1){
return 1;
}
long long int maxDivisor = (x / 2) + 1;
int divisorsCount = 0;
for (long long int i = 2; i<=maxDivisor; i++){
if (x % i == 0){
divisorsCount++;
}
}
divisorsCount += 2; //for 1 & x itself
return divisorsCount;
}
These two files have been compiled with Visual Studio 2012 in Debug mode as a static library.
Now I try to use them in a separate project, let's call it MainProject:
1. Add the "Utils.vcproj" to MainProject solution.
2. Make MainProject to depend on Utils
3. In "Properties"->"Linker"->"Input"->"Additional Dependencies" put the path to Utils.lib
Here is the main which uses Utils:
#include <iostream>
#include "..\Utils\Utils.h"
using namespace std;
int main(){
cout << "num of divisors of " << 28 << ": " << numOfDivisors(28) << endl;
//this part is merely to stop visual studio and look at the output
char x;
cin >> x;
return 0;
}
And this is the error I get:
Error 1 error LNK2019: unresolved external symbol "int __cdecl numOfDivisors(__int64)" (?numOfDivisors##YAH_J#Z) referenced in function _main G:\ProjectEuler\Problem12\Source.obj Problem12
Why can't it find the code which implements "numOfDivisors"? I have given it the .lib which contains it, moreover - put a dependency on the Utils project itself...
Any help would be appreciated.

Assuming the library is correctly built and linked, the next most likely cause of the error is that the function is named something else in the library than it is in the code that links to it.
This could be caused by any number of project settings that affect either name decoration or type names. There's not really any point in guessing from a distance which particular setting is the culprit in your case. You can compare the two projects' properties (either manually or with a diff tool) and try to spot a difference that would result in a different decorated function name.

Looks like method numOfDivisors() is not defined in you Utils.cpp, can you check it once?
And why is your compiler complaining "G:\ProjectEuler\Problem12\Source.obj"? Where is Source.obj coming from?
You have to specify library path in one field and library name in other field, have you specified both under appropriate settings?

Related

Problems with functions in classes C++ (LNK2019 & LNK1120 errors)

I've been working on a project for my college class that uses classes in c++, unfortunately anytime I try to call on a function that is passed parameters within my class the program fails to compile with the two following errors:
Error LNK2019 unresolved external symbol "int __cdecl binsearch(class Course * * const,int,char * const)" (?binsearch##YAHQAPAVCourse##HQAD#Z) referenced in function _main Project1 C:\Users\cvos\source\repos\Project1\Project1\courses_main.obj 1
and
Error LNK1120 1 unresolved externals Project1 C:\Users\cvos\source\repos\Project1\Debug\Project1.exe 1
I've looked up the LNK problems, and most results suggest it's something related to symbols in c++ vs c (That fix doesn't work) or that there is a problem with linking the files within visual studio (That fix also didn't work), and finally that it was something to do with it needing to be on the console subsystem (Which it already was).
The strange thing is, if I comment out my calls to all of the functions I've made in the "Course" class that are passed parameters, the program runs fine. It's only when I am trying to use the functions created in the "Course" class that the program fails to run, leading me to suspect strongly I'm doing something wrong with how I'm passing variables to my member functions.
I'll post the relevant parts of my code:
Within my header file "courses.h" I declare my function:
int binsearch(Course* co_ptr[], int size, char search[]);
Within my 2nd source file "courses_functions.cpp" I define the function:
int Course::binsearch(Course* co_ptr[], int size, char search[])
{
int low = 0, high = size - 1, first_index = -1, last_index = -1, num_of_entries = 0;
while (low <= high)
{
int mid = (low + high) / 2;
if (co_ptr[mid]->name == search)
{
bool found = false;
int i = mid;
while (!found) //Check values below mid
{
if (co_ptr[i]->name == search)
{
first_index = i; //first_index now holds a potential first occurence of our name
if (i == 0)
{
found = true;
}
}
else
{
found = true;
}
i--; //decrement i and check again.
}
i = mid; //Reset i
found = false; //Reset found
while (!found) //Check values above mid
{
if (co_ptr[i]->name == search)
{
last_index = i; //last_index now holds a potential last occurence of our name
if (i == size - 1)
{
found = true;
}
}
else
{
found = true;
}
i++; //increment i and check again.
}
break; //Breaks us out of the main while loop
}
else if (co_ptr[mid]->name < search)
{
low = mid + 1;
}
else
{
high = mid - 1;
}
}
if ((first_index != -1) && (last_index != -1))
{
for (int i = first_index; i <= last_index; i++)
{
std::cout << "\nEntry found: "
<< std::endl << co_ptr[i]->name << ' ' << co_ptr[i]->units << " units, grade:" << co_ptr[i]->grade;
num_of_entries++;
}
return num_of_entries;
}
else
{
std::cout << "\nEntry not found.";
return num_of_entries;
}
}
Lastly in my main source file "courses_main.cpp" I call the function:
else if (selection == 3) //Display a course
{
char title[50] = "";
int results = 0;
std::cout << "\nEnter a class to search for: ";
std::cin.getline(title, 50, '\n');
std::cin.ignore();
results = binsearch(courses, size, title);
}
As this is for a college class, I'm not looking to use any alternative methods, I'm mainly trying to figure out why the method I'm using would return the errors I shared above, but I will gladly post more snippets of my code if it is necessary.
Thanks!
The cause is almost certainly one of the following:
You're not compiling the implementation file (just using the header elsewhere).
You're compiling the implementation, but not using the compiled object in the linking of objects into the executable.
You have some minor mismatch in naming, e.g. using binsearch() not in a class context, or using a slightly different signature somehow (not likely giving what you've told us).
Need to see a declaration of your "courses.h" file. You may have declared binsearch outside of your Course class declaration. In which case you will get a linker error as mentioned.
Based on your usage in main.. your implementation of this function need not be in Course class, it can be a standalone function outside of Course class. once you move your function definition outside of Course class, your linker should go away, provided you have courses_functions.cpp and courses_main.cpp files in same project in your MSVC IDE.

Error LNK2005 in C++ and ifndef don't work

I have a problem with Visual Studio 2012 & 2015 about the fact than it's seem than the "ifndef" don't work. I use the "ifndef" for "NAN" and "ifndef" for the header file and it's said these 2 errors (see the image). When I add the link "#include"Outil.h"" in the header of other file, I see the same message of error.
I always do like this before and it's always work. I don’t understand why it's doesn't work now even with only two files.
I also try to change the name of the first function "realoc_ungraded" but it's doesn't work and I get the same error.
Message of error
The message:
1) Warning: C4005: 'NAN': macro redefinition of math.h
2) Error: LNK2005: "struct tab_dynamo __cdecl realoc_ugraded(struct tab_dynamo,unsigned int)" (?realoc_ugraded##YA?AUtab_dynamo##U1#I#Z) already defined in main.obj Project1
3) Error: LNK1169: one or more multiply defined symbols found Projet
There is the code of the different file:
File main.cpp
#include"Outil.h"
int main(void) {
return 0;
}
File Outil.h
#ifndef LIBRARY_OF_TOOLS
#define LIBRARY_OF_TOOLS 0
#define _USE_MATH_DEFINES
//NAN not defined in Visual Studio 2012, so I use the def. of VS 2015
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
#include<iostream>
#include<string>
using namespace std;
#include<cmath>
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#define ERROR_ADRESSE 0xcccccccc //default when not initialised
#define DEFAULT_LENGHT_TAB 1
//-----------------------------------------
typedef double type_data; //the type for calculation
//-----------------------------------------
/*Struct for my array*/
typedef struct {
type_data *tab;
unsigned int length;
}tab_dynamo;
//-----------------------------------------
template<typename T>
bool verify_ptr(const T *ptr) {
return (ptr == NULL || ptr == (T*)(ERROR_ADRESSE));
}
//-----------------------------------------
template<typename T>
void see_tab(const T *tab, const unsigned int taille) {
unsigned int i;
cout << endl << endl;
if (verify_ptr(tab) == false && taille > 0) {
cout << endl;
for (i = 0; i<taille; ++i) {
cout << tab[i] << "\t";
}
}
cout << endl << endl;
}
//-----------------------------------------
template<typename T>
T* realoc_ungraded(const T* original_tab, unsigned int *length, const unsigned int new_length) {
T* new_tab = NULL;
unsigned int precedent_length = 0, i;
/*1) Exception case to directly exit*/
if (new_length == 0) {
return NULL;
}
/*2) Verification of the ptr of the length*/
if (verify_ptr(length)) {
length = (unsigned int*)calloc(1, sizeof(unsigned int));
assert(length);
}
precedent_length = *length;
*length = new_length;
/*4) Creation of the new tab.*/
new_tab = (T*)calloc(*length, sizeof(T));
assert(new_tab);
/*5) To transfert data of the original tab to the new tab*/
if (precedent_length != 0 && verify_ptr(original_tab) == false) {
for (i = 0; i < precedent_length && i < new_length; ++i) {
new_tab[i] = original_tab[i];
}
}
return new_tab;
}
//-----------------------------------------
//Version with the use of the struct "tab_dynamo"
tab_dynamo realoc_ungraded(tab_dynamo original_tab, const unsigned int new_length) {
tab_dynamo tableau = { NULL, 0 };
tableau.tab = realoc_ugraded(original_tab.tab, &original_tab.length, new_length);
tableau.length = new_length;
return tableau;
}
#endif
File Outil.cpp:
#include"Outil.h"
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
When preprocessor process these, the NAN is defined because it's not defined yet.
#include<cmath>
Then cmath maybe include math.h, and found NAN is defined by yours.
You can try to change the sequence of include and your definition.
#include <cmath>
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
B.T.W If you compile using gcc, you could use -E option to see the output of preprocessor and know how the preprocess expand the macros.

error LNK2019: unresolved external symbol, cannot not link with the cpp file i coded [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
I start learning C++ in school and this error appear.
1>Bettle_Dice.obj : error LNK2019: unresolved external symbol "public: int __thiscall Beetle::checkcom(void)" (?checkcom#Beetle##QAEHXZ) referenced in function _main
I have include other header files and cpp files, I don understand why only this file have problem please help
Below is my code
main.cpp
#include "stdafx.h"
#include "beetle.h"
#include "dice.h"
#include "player.h"
#include <iostream>
using namespace std;
int main()
{
Player p; //declare Class to a variable
Dice d;
Beetle btle;
int temp;
cout << "Number of players?" << endl;
cin >> temp;
p.Num(temp); //store the number of player into class
//cout << p.getNumPlayers() <<endl;
cout << "Start game!!" <<endl;
temp = btle.checkcom();
while(temp != 1)
{
for(int i=0;i<p.getNumPlayers();i++)
{
temp = d.roll();
cout <<"Your roll number:"<< temp;
}
}
return 0;
}
beetle.h
class Beetle
{
private:
int body,head,ante,leg,eye,tail;
public:
int completion();
int checkcom();
int getBody() { return body;};
int getHead() { return head;};
int getAnte() { return ante;};
int getLeg() { return leg;};
int getEye() { return eye;};
int getTail() { return tail;};
};
Beetle.cpp
#include "stdafx.h"
#include "beetle.h"
int completion()
{
return 0;
}
int checkcom()
{
Beetle btle;
int flag = 0;
if(btle.getBody() == 1 && btle.getHead() == 1 && btle.getAnte() == 2 && btle.getEye() == 2 && btle.getLeg() ==6 && btle.getTail() == 1)
flag = 1;
return flag;
}
I checked some solution on the internet, some are saying is the library problem, but this file is not a built-in function. I guess it is not the problem of the library. I tried to include the beetle.obj file to it and the debugger said it is included already and duplicate definition.
In the other file, i do not have "bettle" this word. It should not be the problem of double declaration or duplicate class.
I have no idea what the problem is. Please help.
You need to prefix the signature of your class functions with the class name Beetle::
Otherwise the compiler just thinks those functions are global functions, not member functions.

How do you get file information for variables in unnamed namespaces from PDB files?

I need to get the filenames from a PDB file which correspond to variables in unnamed namespaces. I'm using VS2012 and C++. I have put together a small sample of trivial code to illustrate the problem:
// file: unnamed_namespace1.cpp Minimal test for anonymous namespace symbols
namespace {
float x;
static float xx;
}
int unnamed_namespace1(int data) {
x = 1.0f;
if (data == 0) {
// Computation
xx = x;
} else {
xx = 0.0;
}
return 1;
}
// file unnamed_namespace2.cpp Minimal test for anonymous namespace symbols
namespace {
float x;
float y;
float z;
static float xx;
static float yy;
static float zz;
}
int unnamed_namespace2(int data) {
x = 1.0f;
if (data == 0) {
// Computation
xx = x;
} else {
xx = 0.0;
}
return 2;
}
// file main.cpp
#include <iostream>
using std::cout;
using std::endl;
int unnamed_namespace1(int data);
int unnamed_namespace2(int data);
int main(int /* argc */, char** /* argv */) {
int r1 = unnamed_namespace1(0);
cout << "r1=" << r1 << endl;
int r2 = unnamed_namespace2(1);
cout << "r2=" << r2 << endl;
}
I need some way to look into the PDB file and get enough information to discriminate between the two instances of x and xx in the separate compilands.
I downloaded and played a bit with a project called dia2dump (from https://msdn.microsoft.com/en-us/library/b5ke49f5.aspx), which did help a bit with understanding how the DIA system works, in contrast to the MSDN "documentation" on IDiaSymbol which mostly lacks any context, and has very little in the way of meaningful code examples.
It appears that there is not a good way to tie the symbols x and xx back to the source file names.
I can get an IDiaSymbol* pSymbol, but the various functions that look like they might actually provide what I need all return S_FALSE: "A return value of S_FALSE means the property is not available for the symbol."
Here's a snippet of some code I inserted in dia2dump:
BSTR bstrFname;
if (pSymbol->get_sourceFileName(&bstrFname) == S_OK) {
wprintf(L"fn:%s ", bstrFname); // <== never gets here
SysFreeString(bstrFname);
}else{
wprintf(L"no fn "); // <== this is always printed
}
I was unable to locate any clues for why get_sourceFileName() doesn't return anything useful.
I'm guessing that I'm either 1) looking in the wrong place, or 2) the programmers who wrote the Debug Interface Access DLL didn't consider it important enough to implement that feature for symbols in anonymous namespaces. I'm hoping it's #1, so that somebody out there can point out whatever it is that I have managed to overlook.
It's even ok to make fun of my ignorance, as long as you provide usable information...

Error C3861: 'ResGain': identifier not found

essentially I'm writing a short script. The easiest way to look at is that it's for a game with a resource collection. ResGain is the resources gained, and BonusGain is the chance to earn an extra resource. I am getting Identifier not found errors for the ResGain and Bonus Gain functions, but I have declared the ResGain and BonusGain functions before main. Any ideas why?
#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float ResGain(float u, int r) //calc Base resource Gain
{
float lapout;
lapout = r * u;
return (lapout);
}
char BonusGain(int b) //Determines if a bonus material would be produced.
{
char bonus;
int rng;
rng = rand() % 100 + 1;
if (rng <= b)
bonus = 1;
return(bonus);
}
int main()
{
float l;
l = ResGain(1.1,70);
cout << "You have earned" << l << "Lapis";
if (BonusGain(3)==1)
cout << "You have also earned a bonus material";
system("pause");
return 0;
}
Most probably the identifier not found is system() which is not part of the standard library. You should locate the Windows-specific header where it is declared.