I am trying to compile a C++ using g++ in Linux which uses some functions defined in a header file crated by someone. I am not much experienced with C++ so I am not sure how to proceed (or even if I understand what should be done).
I have all these files in a single directory:
PaLaser.cxx, this is the main.
USBM3.h
hidapi.h
hidapi.lib
hidapi.dll
USBM3.lib
USBM3.dll
This was created by someone for Windows and now I want to compile for Linux. The USBM3.h looks like this:
#include <sstream>
#include <string.h>
using namespace std;
class HIDDLL
{
private:
static void init();
static void SendDataToUSB();
static int parseChar(unsigned char );
static void ParseByte(string);
static int openFile(char *);
static void SendFile();
static void readADC();
public:
/* This method is used to generate sequence */
static __attribute__((visibility("default"))) void seqMODE(int mode);
/* This method is used to turn off LASER */
static __attribute__((visibility("default"))) void LASERTurnOff(void);
/* This method is used to send freq data to ARM */
static __attribute__((visibility("default"))) void sendFreq(int freq);
bla bla bla
};
and in the PaLaser.cxx there is this:
#include "hidapi.h"
#include "USBM3.h"
#pragma comment(lib, "USBM3.lib")
When I run
g++ PaLaser.cxx -o PaLaser
I get
/usr/bin/ld: /tmp/ccUXpAbN.o: in function `main':
PaLaser.cxx:(.text+0x1e): undefined reference to `HIDDLL::isDeviceAttached()'
/usr/bin/ld: PaLaser.cxx:(.text+0x33): undefined reference to `HIDDLL::readLASERstate()'
.............
where ........... stands for all the things defined in USBM3.h.
I have no certainty whether these things are packed within the USBM3.lib file, but I hope they are. How do I tell g++ to look there?
Related
I am a beginner in C and slightly more advanced in C++. This is my first time using make.
I have a large C++ library (written by a third-party that I need to integrate into a C pipeline) and I am hoping to call this library from C. In order to call the C++ library from C, I have 3 files: a .cpp file implementing the calls to the C++ library with C-compatible data types, a .h C-compatible header file linking the C++ implementation functions to C, and a .c file with a main() function that calls the C++ function with C-appropriate data types.
The header file (random_forest.h):
#ifndef RANDOMFOREST_H_
#define RANDOMFOREST_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
// opaque forward declared struct
struct random_forest_model;
// pointer to struct used by C code
typedef struct random_forest_model* random_forest_model_t;
random_forest_model_t random_forest_new(const char* model_file_path);
void random_forest_free(random_forest_model_t random_forest_model);
uint8_t *classify(
random_forest_model_t random_forest_model,
const double* independentVariableData,
const double* dependentVariableData,
const size_t numberRows,
const size_t numberColumns,
const char** independentVariableNames
);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* RANDOMFOREST_H_ */
In my random_forest.cpp file:
#include <memory.h>
#include "/src/random_forest.h"
#include "/src/rf/src/Forest.h"
#include "/src/rf/src/globals.h"
#include "/src/rf/src/ForestClassificationPrediction.h"
#include "/src/rf/src/utility.h"
using namespace rf; /* comes from Forest.h file */
struct random_forest_model {
std::unique_ptr<rf::Forest> forest;
std::string model_file_path;
}
namespace {
std::unique_ptr<rf::Forest> random_forest_acquire(const char* model_file_path) {
try {
std::unique_ptr<rf::Forest> forest = make_unique<ForestClassificationPrediction>();
forest->InitPredictionModelCpp(model_file_path);
return forest;
} catch(...) {
return nullptr;
}
}
} /* anonymous namespace */
random_forest_model_t random_forest_new(const char* model_file_path) {
try {
auto forest = random_forest_acquire(model_file_path);
return new random_forest_model{std::move(forest), model_file_path};
} catch (...) {
return nullptr;
}
}
void random_forest_free(random_forest_model_t random_forest_model) {
delete random_forest_model;
}
uint8_t* classify(
ranger_random_forest_model_t ranger_random_forest_model,
const double* independentVariableData,
const double* dependentVariableData,
const size_t numberRows,
const size_t numberColumns,
const char** independentVariableNames
) {
try {
/* bunch of stuff here to convert data and run classification */
} catch(...) {
return nullptr;
}
}
Then in my random_forest_implement.c file:
#include "/src/random_forest.h"
int main() {
const char model_file_path[] = "path/to/model";
random_forest_model_t random_forest = random_forest_new(model_file_path);
/*
some code here to ingest a data file - outputting the data for random_forest_classify
yielding: X, y, numberRows, numberColumns, varNames
*/
uint8_t *classes = classify(
random_forest, X, y, numberRows, numberColumns, varNames
);
random_forest_free(random_forest);
free(X);
free(y);
free(varNames);
free(classes);
return EXIT_SUCCESS;
}
This is a very long-winded way to ask how to compile this program into a single executable. I've tried to compile with the following make file:
CC ?= gcc
CP ?= g++
random_forest_implement: random_forest_implement.o random_forest.o
$(CP) -o random_forest_implement random_forest_implement.o random_forest.o
random_forest.o: random_forest.cpp random_forest.h
$(CP) -c random_forest.cpp
random_forest_implement.o: random_forest_implement.c random_forest.h
$(CC) -c random_forest_implement.c random_forest.h
clean:
$(RM) *.o random_forest
When I try to make this (make -f random_forest_make.mk), I get three lines that appear (?) successful, and I receive a lot of errors about undefined reference, e.g.:
cc -c random_forest.c random_forest.h
g++ -c random_forest.cpp
g++ -o random_forest_implement random_forest_implement.o random_forest.o
/usr/bin/ld: random_forest.o: in function `(anonymous namespace)::random_forest_acquire(char const*)':
random_forest.cpp:(.text+0x44f): undefined reference to `rf::Forest::InitPredictionModelCpp(<bunch of args necessary to method>)
I'm not entirely sure where to go from here, but I suspect I'm not compiling everything correctly. As you can see, I have several files on which my random_forest.cpp file depends. Do I need to compile each of these? And their dependencies? Is there a best/efficient method for doing this, or do I need to write a make file that generates an object file for every .cpp file in the /src/rf/src/ directory?
You cannot build a C executable including C++ sources. You can only create C++ executables if you include any C++ code. C++ supports C source modules to be linked against for compatibility reasons but C compilers were not designed to link C++ modules (there’s no backwards compatibility between C and C++, C was created before)
For this reason, you can only use c++ compiler to link C++ mixed with C sources (even if main is defined in a C source file) because this action will make C++ compiler to call the linker in C++ mode and link both C/C++ modules and call the C++ standard library modules and run time. Despite of the similarities between both languages, the memory layout of a C++ executable is more complex than the layout of a simple C-only program
I'm using the d3dx9.h header to be able to use many of the Direct3D functions and datatypes. One of which is 'D3DXVECTOR3'. I have stumbled upon a weird issue of which I can't find the cause:
I have two files, Link.h and Link.cpp. Link is a static class. In my Link.cpp and Link.h I have included the d3dx9.h file as follows:
#ifndef D3DX9_INCLUDED
#define D3DX9_INCLUDED
#include <d3dx9.h> // Direct3D 9
#endif
In Link.cpp I have created a function to get a D3DXVECTOR3 variable:
#pragma once
#ifndef D3DX9_INCLUDED
#define D3DX9_INCLUDED
#include <d3dx9.h> // Direct3D 9
#endif
namespace Core
{
static class Link
{
private:
public:
static struct D3DXVECTOR3 getVector()
};
}
My Link.h script makes this public:
static struct D3DXVECTOR3 getVector();
Now, when I call this function from outside this class it keeps giving me the error
error C2027: use of undefined type 'Core::D3DXVECTOR3'
This is how I call the getVector function:
Core::Link::getVector();
I get the error even though D3DXVECTOR3 is not a member of 'Core'. I have included d3dx9.h the same way outside this class.
I have tried exactly the same with standard datatypes such as a bool, worked like a charm. Why does getVector return a D3DXVECTOR3 as a child of Core?
Screen.h
#ifndef SCREEN_H
#define SCREEN_H
#include <SFML/Graphics.hpp>
class Screen
{
public:
virtual void handleInput(sf::RenderWindow& window) = 0;
virtual void update(sf::Time delta) = 0;
virtual void render(sf::RenderWindow& window) = 0;
};
#endif
Game.h
#ifndef GAME_H
#define GAME_H
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <vector>
#include <memory>
#include "Screen.h"
namespace sfSnake
{
class Game
{
public:
Game();
void run();
void handleInput();
void update(sf::Time delta);
void render();
static const int Width = 640;
static const int Height = 480;
static std::shared_ptr<Screen> Screen;
private:
sf::RenderWindow window_;
sf::Music bgMusic_;
static const sf::Time TimePerFrame;
};
}
#endif
I have problems with these two headers. The code compiles fine with visual studio but won't with GCC.
I get the errors:
Description Resource Path Location Type
error: changes meaning of ”Screen” from ”class Screen” [-fpermissive] Screen.h /Snake line 6 C/C++ Problem
error: declaration of ”std::shared_ptr<Screen> sfSnake::Game::Screen” [-fpermissive] Game.h /Snake line 28 C/C++ Problem
I have looked around for a while now and haven't found a solution. I really feel lost...
Also this is not my code it was written by the user 'jh1997sa' on reddit. The source on github. His thread on reddit.
You haven't named your platform, but I presume it's some flavor of Linux running X11. If so, this is most likely a name conflict with the Screen struct defined in X11/Xlib.h. SFML is almost certainly using Xlib behind the scenes to interact with the windowng system.
Because Xlib is a C library, all symbols it defines live in the global namespace. Fortunately in C++ you have the option of putting your Screen class in a namespace of your choosing. As long as you then refer to it by its fully qualified name, you can avoid the name clash.
From what I understand, if you are trying to compile on a linux system you should be using g++ to compile instead of gcc.
[EDIT:]
The problem seems to belong to the functions, that take default-parameters. Without separating in *.h *.cpp and main file it worked as i implemented something like:
void foo(double db;); // deklaration
void foo(double db = 4){ cout << db;} // definition
int main(){
foo(); // usage
return 1;
}
But if I separate deklaration (-> *.h), definition (-> *.cpp) and usage (-> main) compiling suddenly returns an erro telling, there is no function foo(void), as it does not recognize that there is a default parameter. Any suggestions for that?
[/EDIT]
I wrote a c++-program running somehow like:
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
private:
/* variables */
public:
/* function deklarations (just some short ones are only defined not declared) */
};
ostream& operator<<(ostream &out, my_class member);
/* Definition of the member functions and of the not-member-function */
int main()
{
/*some trial codes of member-functions */
return 1;
}
In one total file all compiled well in Eclipse and worked. Now I also wanted to try seperate in a main,class-header and class-cpp file (called them "my_class.h" and my_class.cpp").
For that i put in class-header:
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
/* ... */
};
ostream & operator<<(ostream &out, my_class member);
#endif /* MY_CLASS_H_ */
I put in class-cpp:
/* Definition of the member functions and of the not-member-function */
I put in main:
#include <iostream>
#include "my_class.h"
#include "my_class.cpp"
int main()
{
/*some trial codes of member-functions */
return 1;
}
This version is compiling with the g++ command in commandline:
g++ -o main.exe main.cpp
But it does not Compile in Eclipse. There it gives me the Error:
...\my_class.cpp:11.1: error: 'my_class' does not name a type
and same for all other member functions and variables. I tried to follow the instructions from here (I put just "my_class.h" in main and my_class.cpp, but then it did not compile in Eclipse and in command line (of course then with the my_class.cpp included). Eclipse gives me an Error, that makes me believe Eclipse does not see the "my_class.cpp":
...\main.cpp:288:47: error: no matching function for call to 'my_class::foo(...)'
where foo stands for the first member-function declard in the "my_class.cpp" file. First It gave the error for the constructor too, but as I put it's definition directly into the *.h file it worked well. (That's why I think, it does not see the "my_class.cpp" file)
I think I might be missing something very trivial as I am very new to Eclipse, but I don't see it. I tried to make my questions and information as short as possible.
default-parameters need to be declared in the header-file as it contains the declarations and not in the cpp file, which contains the definitions. (An additional mistake was to declare them in the definition). Found some help here. But why did it work, as I implemented it in one whole file?
Answer:
If default-parameter is in the cpp-file, the main file does not see it as
it looks only into the header-file
But if the whole code is included in just one file, the default-value
can be found in the definition too.
To explain myself:
I considered answering my question, because it gives a better overview of the whole question and the question will now not appear as unanswered. After reading this, I think that it is the right way to do so.
I have a noob question here.
I'm getting my head around the C++ structure and syntax and I've hit a bit of a wall.
I know I am missing something from my concept. So first a little code to help describe the situation.
Control.h
#pragma once
#ifndef CONTROL_H
#define CONTROL_H
class Control
{
public:
Control();
~Control();
private:
public:
};
#endif /*CONTROL_H*/
Control.cpp
#include "Control.h"
#include "Hello.h"
Hello helloObj;
Control::Control()
{
}
Control::~Control()
{
}
int main()
{
int a = helloObj.HelloWorld();
return 0;
}
Hello.h
#pragma once
#ifndef HELLO_H
#define HELLO_H
class Hello
{
public:
Hello();
~Hello();
private:
public:
int HelloWorld(void);
};
#endif /*HELLO_H*/
Hello.cpp
#include "Hello.h"
Hello::Hello()
{
}
Hello::~Hello()
{
}
int HelloWorld()
{
return 5;
}
I try and compile control.cpp with g++ on OSX 10.7 and get
Undefined symbols for architecture x86_64:
"Hello::Hello()", referenced from:
__static_initialization_and_destruction_0(int, int)in cccZHWtd.o
"Hello::~Hello()", referenced from:
___tcf_1 in cccZHWtd.o
"Hello::HelloWorld()", referenced from:
_main in cccZHWtd.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Is it the compiler, my code or my concept of whats going on?
Am I not instantiating something correctly?
Any links describing this in more detail would be appreciated.
Ultimately I want to be able to run a function in another class and return the result...normal OO, keeping your program modular stuff....
The errors you are getting are Linking errors not compilation errors.
The linker is not able to find definitions of the said functions & hence it reports the errors. It seems You have not included the Hello.cpp file containing the function definitions in your project.
Make sure Hello.cpp is included in your project and is a part of your project or
If you are using command line for compilation and linking make sure you have specified Hello.cpp in the file names on the command line.
Most of the issue is me not being familiar as I should be with g++ (Thanks Als).
There were are few syntax issues as well (Thanks Brain).
Here is the corrected (albiet slightly bloated for an overview of stucture) code and g++ command
Control.h
#pragma once
#ifndef CONTROL_H
#define CONTROL_H
class CONTROL
{
private:
//nothing defined yet...
public:
Control(); //default constructor
~Control(); //default destructor
};
#endif /*CONTROL_H*/
Control.cpp
#include "Hello.h"
#include "Control.h"
Hello helloTest; //instantiates the Hello Object
Control::Control()
{
}
Control::~Control()
{
}
int main()
{
helloTest.HelloWorld();
return 0;
}
Hello.h
#pragma once
#ifndef HELLO_H
#define HELLO_H
class Hello
{
private:
//nothing defined yet
public:
Hello(); //default constructor
~Hello(); //default destructor
void HelloWorld();
};
#endif /*HELLO_H*/
Hello.cpp
#include "Hello.h"
#include <iostream> //so we can use 'cout'
using namespace std;
Hello::Hello()
{
}
Hello::~Hello()
{
}
void Hello::HelloWorld()
{
std::cout << "Hello lovelies!\n"; //The magic word.
}
Then we run g++ like so
g++ -o Hello ./Control.cpp ./Hello.cpp
g++ [option] [output file name] [input files]
First of all:
public:
Hello();
~Hello();
private:
public:
is pointless, a class defaults to private, and there is no need to make it
public twice nor do I know if you can do that furthermore if you have no private members private should not be in there (not trying to be mean just some advice :-) )
Now to answer the question (with a guess DISCLAIMER: I AM NOT 100% FAMILIAR WITH GCC):
This is a linker error, it may be there because
the compiler can not find the definition of
HelloWorld(void);.
Let me explain:
In your header file you wrote:
int HelloWorld(void);
However in your .cpp you write:
int HelloWorld()
{
return 5;
}
The function's (or in this case method because it is inside a class)
arguments need to be exactly the same in the header and source, you
can not even change the names (or at least you cant with VC++ which is
what I use; I have little experience with gcc) so this may be resolvable
by typing
int HelloWorld(void)
{
return 5;
}
Next (DISCLAIMER I AM NOT 100% familiar with the pre-proccsor):
You also use the #pragma once pre-proccsor tag, I dont use it but
I believe that means you can only include a file once and you have included Hello.h and Control.h twice, like I said I am no expert in the pre-proccsor but you commented out
HELLO_H
and
CONTROL_H