unresolved external symbol, ATIDAQ, VisualStudio - c++

I'm extremely confused and have been going in circles for about the past hour with this now.
I am attempting to add the ATIDAQ C Library to my project zip link here for the ATIDAQ C Library. In my project I have added:
C/C++->General->Additional Include Directories: <PATH_TO_LIB>\ATIDAQ C Library\ATIDAQ
However I keep getting the error LNK2001: unresolved external symbol _createCalibration
main.cpp
extern "C" {
#include <ftconfig.h>
}
int main(int argc, char* argv[]) {
char *calfilepath; // name of calibration file
unsigned short index; // index of calibration in file (second parameter; default = 1)
Calibration *cal = NULL; // struct containing calibration information
unsigned short i, j; // loop variables
index = 1;
calfilepath = argv[1];
cal = createCalibration(calfilepath, index);
printf(" Serial: %s\n", cal->Serial);
printf(" Body Style: %s\n", cal->BodyStyle);
}
Which is I think caused by the line C/C++->General->Additional Include Directories: <PATH_TO_LIB>\ATIDAQ C Library\ATIDAQ. The IDE finds the Calibration *createCalibration(char *CalFilePath, unsigned short index); function (as this is not syntax highlighted and tab completes).
I'm really unsure what is going, wrong. I think I am missing something with the linker, but I am just not sure as to what.

The ATIDAQ C Library doesn't provide a .lib for you to link against; instead, you should instruct the Visual C++ compiler to compile the necessary C source files in the same folder. In this case, createCalibration is implemented in ftconfig.c.

Related

Undefined Symbol When Mixing C and C++ Code

I'm just getting started using nauty, which is written in C. Nauty comes with a program called geng that produces a file of graphs, but it's possible to call it from your own program, and work with the graphs one at a time. A sample C program is provided, and I'm trying to convert it to C++. The comments at the top of the program describe the general approach. I've listed both my program and geng.c, the source code from nauty, in my target.
Here's my code
/* This is a sample of how to call geng as a procedure rather than
* running it as a separate process. The basic idea is to construct
* an argument list for geng's main() function. At compile time,
* assign a name to the macros OUTPROC and GENG_MAIN. A typical
* Unix-style compilation command would be:
gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main \
callgeng.c geng.c nauty.a
*/
extern "C" {
#include "gtools.h"
}
static unsigned long counter;
extern "C" void
OUTPROC(FILE *outfile, graph *g, int n)
{
/* This will be called for each graph. */
++counter;
}
int GENG_MAIN(int geng_argc, char* geng_argv[]);
int
main(int argc, char *argv[])
{
int geng_argc;
char *geng_argv[6];
// Set up geng argument list. The 0-th argument is the command name.
// There must be a NULL at the end. This example is for trees
// of order 16.
char argv0[] = "geng";
char argv1[] = "-q";
char argv2[] = "-cbf";
char argv3[] = "16";
char argv4[] = "15";
geng_argv[0] = argv0;
geng_argv[1] = argv1;
geng_argv[2] = argv2;
geng_argv[3] = argv3;
geng_argv[4] = argv4;
geng_argv[5] = NULL;
geng_argc = 5;
counter = 0;
GENG_MAIN(geng_argc,geng_argv);
printf("Number of graphs = %lu.\n",counter);
return 0;
}
The program geng.c contains the lines:
#ifdef GENG_MAIN
int
GENG_MAIN(int argc, char *argv[])
#else
int
main(int argc, char *argv[])
#endif
When I try to build the project, it fails with a linker error:
Undefined symbols for architecture x86_64: "_geng_main", referenced
from:
_main in my_callgeng.o ld: symbol(s) not found for architecture x86_64
I tried compiling from the command line and it works fine.
>gcc -o callgeng -O3 -DMAXN=32 -DOUTPROC=myoutproc -DGENG_MAIN=geng_main -I/Users/saul/nauty26r7 my_callgeng.cpp ~/nauty26r7/geng.c ~/nauty26r7/nauty.a
>./callgen
Number of graphs = 19320.
So, it looks like an Xcode problem.
This was an Xcode error. I didn't realize that I had to put the compiler flags on each each line under BuildPhases/Compile Sources, so I only had "-DGENG_MAIN=geng_main" for my code, not for geng.c. Therefore the substitution didn't take place when geng.c was compiled, and it must have compiled _main, not _geng_main.
In your code (not geng.c), you need to add the extern "C" in front of
int
GENG_MAIN(int argc, char *argv[])
so that the compiler knows that this function (from geng.c) must use C linkage within your C++ instead of the default C++ linkage for that function (what you get when you don't specify in a file full of C++ code).
Basically, the C++ file uses C++ linkage for functions by default, and the C code uses C linkage for functions, so when you want the C code to be able to call something from the C++ code (your GENG_MAIN) you must specify in the C++ code that that particular function must be compiled with C linkage even though it is internally C++.

Creating class object defined in another project

I have a Visual C++ solution with 2 projects: rectangle and project3.
In rectangle project I have rect.cpp and rect.h.
rect.h
#ifndef rect_h
#define rect_h
class Rect
{
public:
Rect();
int m_h;
int m_w;
};
#endif //rect_h
rect.cpp
#include "rect.h"
Rect::Rect()
{
m_h = 1;
m_w = 5;
}
whenever I try to create rect object from the rectangle project it succeeds.
But when I try to do the same from the project3 it produces a linker error.
LNK2019: unresolved external symbol "public: __thiscall
Rect::Rect(void)" (??0Rect##QAE#XZ) referenced in function _main
1>C:\Users\mbaro\documents\visual studio
2017\Projects\Project2\Debug\Project3.exe : fatal error LNK1120: 1
unresolved externals
main.cpp (in project 3)
#include "rect.h"
using namespace std;
int main()
{
Rect* a = new Rect();
return 0;
}
I kind of feel that class definition is picked up successfully, but the linker can not link the constructor code from rect.cpp.
What is the problem and how to solve it?
Thanks.
The error is normal: you told the compiler where it could find the .h files, but you did not tell the linker where it could find the .obj files.
It may depend on the exact VS version, but in Project/Properties, you should find Linker/Input and there Additional dependencies. If you only need one or two object files (xxx.obj) from the other project, add them here. That way, you avoid code duplication, which will be a nightmare for future maintenance...
If you have many common files, you should considere to put them in an auxilliary project that would build a (static)library in the same solution, and then link the library in both project (and of course give access to header files of the library project for the other projects using the library).
I have already started writing a long, long answer. Then i realized, what You may be missing is that despite Your class is named "Person" the header file You should have added is named "rect.h".
Also Your constructor cannot have a declaration of values in the header file (EDIT:not true, I was mistaken). In the header file, try using:
Person(int h, int w);
You declare what will be needed, not what You already have. If You want those to be specifically what You wrote the constructor should be:
Person();
in .h
and
Person::Person()
{
m_h = 1;
m_w = 5;
}
in .cpp.
If You need more detailed description of using include, I have already written a big part of it, so don't hesitate to ask.

Unresolved externals and extern "C"?

As new as I am to C++, I don´t fully understand this linking and stuff.
And I think this is about extern "C" linking.
extern "C"
{
int loadbmp(char *filename, unsigned char **buf,
int *w, int *h, int pf, int bottomup);
const char *bmpgeterr(void);
}
unsigned char *srcBuf=NULL, **jpegBuf=NULL;
unsigned long jpegsize=0;
int width, height;
char *filename={"Screenshot158139.bmp"};
tjhandle handle=NULL;
void main(){
if(loadbmp(filename, &srcBuf, &width, &height,TJPF_RGB, 0)==-1){
//printf("Could not load bitmap: %s\n", bmpgeterr());
exit(1);
}
if((handle=tjInitCompress())==NULL) {
printf("Could not initialize compressor: %s\n", tjGetErrorStr());
free(srcBuf);
exit(1);
}
if((tjCompress2(handle, srcBuf, width, 0, height, TJPF_RGB,
jpegBuf, &jpegsize, TJSAMP_444,10, 0))==-1) {
printf("Could not compress: %s\n", tjGetErrorStr());
free(&srcBuf);
tjDestroy(handle);
exit(1);
}
}
The problem I get from this is that I need to resolve the extern "C" code I think:
error LNK2001: unresolved external symbol loadbmp
Sadly, I don´t know how to do that, and as this error is extremely common in the C++ world, finding an answer for this is not that easy as they can differ.
Hopefully it´s pretty easy to solve this, as I guess I must define it or something as it´s external code.
It seems you have declared loadbmp() but you haven't defined it. Where is the function defined? If it is supposed to come from a library, do not declare this function yourself but rather include the relevant header. The documentation of the function should tell you which is the relevant header and it should mention which extra libraries you may need to include.
If loadbmp() isn't function you want to take from a library, you need to define (implement) it.
What you are missing is linking to your .lib file. Often a quick and easy way is to add this line to the top of the file
#pragma comment(lib,"put_your_lib_filename_here.lib")

Compiler Error __ZTVN13..6..E

I'm currently struggeling with a compilerproblem. The problem is, that i use one of the MoSync example apps called "European Countries" (written in c++) to write my own. But when i compile the modified code, it gives me following error in response:
Controller.cpp:24: Error: Unresolved symbol '__ZTVN13Flightmanager6FlightE',
I already had a look at the example several times and i already copied the code from the example to mine, but it doesn't solve any problems.
In paticutlar i might understand what the error means (i do have c experience), but i've never seen such structured error. I also looked at namespacing conventions but there shouldn't be any problems.
//Flight.h
namespace Flightmanager
{
class Flight
{
public:
static int flightCounter;
/**
* The constructor creates the user interface.
*/
Flight(char *flightnumber, char *gate, char *departure, char *additionalinfo, char *destinationairport, char *destinationairportshort) {
this->_id = flightCounter;
flightCounter ++;
this->_flightnumber = flightnumber;
this->_gate = gate;
this->_departure = departure;
this->_additionalinfo = additionalinfo;
this->_destinationairport = destinationairport;
this->_destinationairportshort = destinationairportshort;
}
virtual ~Flight();
}
//Controller.h
#include [all other includes]
#include "../Model/Flight.h"
namespace Flightmanager
{
Controller::Controller():
mFlightArray(NULL),
mCurrentlyShownScreen(NULL)
{
initScreenSizeConstants();
initPlatformType();
//error: Unresolved symbol '__TZVN13Flightmanager6FlightE'.
initData();
//error: Unresoled symbol '__TZVN13Flightmanager6Flight13flightCounterE'.
mFlightTableView = new TableViewController(*this);//error: Unresoled symbol '__TZVN13Flightmanager6Flight13flightCounterE'.
mFlightDetailView = new DetailViewController();
}
}
I use MoSync Version 3.2
Build date: 121219-1556
Thx
You need to link in something that has definitions for:
Flight::flightCounter
Flight::~Flight()
whether that's a .o object file for Flight.cpp (or some source file) or a library depends on your project.

C++ undefined reference to defined function

I cannot figure out why this is not working. I will put up all three of my files and possibly someone can tell me why it is throwing this error. I am using g++ to compile the program.
Program:
#include <iostream>
#include "h8.h"
using namespace std;
int main()
{
char sentence[MAX_SENTENCE_LENGTH];
char writeTo[] = "output.txt";
int distanceTo,likePosition, length, numWords;
cout << "ENTER A SENTENCE! ";
cin.getline(sentence, 299);
length = strlen(sentence);
numWords = wordCount(sentence, length);
for(int x = 0; x < 3; ++x)
{
likePosition = likePos(numWords);
distanceTo = lengthTo(sentence, likePosition, length);
insertLike(sentence, distanceTo, length, writeTo);
}
return 0;
}
Function file:
void insertLike(const char sentence[], const int lengthTo, const int length, char writeTo[])
{
char part1[MAX_SENTENCE_LENGTH], part2[MAX_SENTENCE_LENGTH];
char like[] = " like ";
for(int y = 0; y < lengthTo; ++y)
part1[y] = sentence[y];
for(int z = lengthTo+1; z < length - lengthTo; ++z)
part2[z] = sentence[z];
strcat(part1, like);
strcat(part1, part2);
writeToFile(sentence, writeTo);
return;
}
Header file:
void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]);
The error exactly is:
undefined reference to 'insertLike(char const*, int, int, char const*)'
collect2: ld returned 1 exit status
The declaration and definition of insertLike are different
In your header file:
void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]);
In your 'function file':
void insertLike(const char sentence[], const int lengthTo, const int length,char writeTo[]);
C++ allows function overloading, where you can have multiple functions/methods with the same name, as long as they have different arguments. The argument types are part of the function's signature.
In this case, insertLike which takes const char* as its fourth parameter and insertLike which takes char * as its fourth parameter are different functions.
Though previous posters covered your particular error, you can get 'Undefined reference' linker errors when attempting to compile C code with g++, if you don't tell the compiler to use C linkage.
For example you should do this in your C header files:
extern "C" {
...
void myfunc(int param);
...
}
To make 'myfunc' available in C++ programs.
If you still also want to use this from C, wrap the extern "C" { and } in #ifdef __cplusplus preprocessor conditionals, like
#ifdef __cplusplus
extern "C" {
#endif
This way, the extern block will just be “skipped” when using a C compiler.
You need to compile and link all your source files together:
g++ main.c function_file.c
This could also happen if you are using CMake. If you have created a new class and you want to instantiate it, at the constructor call you will receive this error -even when the header and the cpp files are correct- if you have not modified CMakeLists.txt accordingly.
With CMake, every time you create a new class, before using it the header, the cpp files and any other compilable files (like Qt ui files) must be added to CMakeLists.txt and then re-run cmake . where CMakeLists.txt is stored.
For example, in this CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8.11)
project(yourProject)
file(GLOB ImageFeatureDetector_SRC *.h *.cpp)
### Add your new files here ###
add_executable(yourProject YourNewClass.h YourNewClass.cpp otherNewFile.ui})
target_link_libraries(imagefeaturedetector ${SomeLibs})
If you are using the command file(GLOB yourProject_SRC *.h *.cpp) then you just need to re-run cmake . without modifying CMakeLists.txt.
If you are including a library which depends on another library, then the order of inclusion is also important:
g++ -o MyApp MyMain.o -lMyLib1 -lMyLib2
In this case, it is okay if MyLib1 depends on MyLib2.
However, if there reverse is true, you will get undefined references.
As Paul said, this can be a linker complaint, rather than a compiler error. If you read your build output/logs carefully (may need to look in a separate IDE window to see the full details) you can dell if the problem is from the compiler (needs to be fixed in code) or from the linker (and need to be fixed in the make/cmake/project level to include a missing lib).