G++: Undefined reference to class::method - linux

I am trying to create an interface for my program using SDL2. The problem is that when I include my .h file, the compiler can't find the .cpp even tough I linked everything. None of the methods I found on the internet work and when compiling in visual studio, the code works perfectly fine. What is more strange is that when I try to make my classes inherit from others, I get the same error from the parent class. I am also using the latest version of Ubuntu. Furthermore, I installed all the libraries required for SDL2.
This is the error:
/usr/bin/ld: /tmp/ccWHZ70h.o: in function `interface::init(char const*)':
interface.cpp:(.text+0xd6): undefined reference to `interface::renderer'
/usr/bin/ld: interface.cpp:(.text+0xdd): undefined reference to `interface::renderer'
/usr/bin/ld: interface.cpp:(.text+0x106): undefined reference to `interface::renderer'
/usr/bin/ld: /tmp/ccWHZ70h.o: in function `interface::LoadTexture(char const*)':
interface.cpp:(.text+0x1bd): undefined reference to `interface::renderer'
/usr/bin/ld: /tmp/ccWHZ70h.o: in function `interface::DrawTexture(SDL_Texture*, SDL_Rect, SDL_Rect)':
interface.cpp:(.text+0x20d): undefined reference to `interface::renderer'
collect2: error: ld returned 1 exit status
make: *** [MakeFile:2: all] Error 1
I compile using make -f on this file:
all:
g++ mainClient.cpp client.cpp interface.cpp -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -o client.exe
clean:
rm -f *~client-exe
The code works perfectly fine without the interface class.
This is the inteface.h code:
#pragma once
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_render.h>
#include <iostream>
class interface
{
private:
int width, height;
SDL_Window* window;
bool state;
static SDL_Renderer* renderer;
public:
interface(int w,int h);
~interface(){};
int init(const char* titlu);
void loop();
void render();
SDL_Texture* LoadTexture(const char* filename);
void DrawTexture(SDL_Texture* tex, SDL_Rect imgRect, SDL_Rect destRect);
};
And this is the interface.cpp code:
#include "interface.h"
interface::interface(int w, int h)
{
width = w;
height = h;
state = true;
}
int interface::init(const char* title)
{
if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
{
window = SDL_CreateWindow(title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,width,height,0);
if(window == NULL)
{
std::cout<<"Eroare la crearea ferestrei!\n";
state = false;
}
renderer = SDL_CreateRenderer(window,-1,0);
if(renderer == NULL)
{
std::cout<<"Eroare la crearea rendererului!\n";
state = false;
}
else
{
SDL_SetRenderDrawColor(renderer,255,255,255,255);
}
}
else
{
std::cout<<"ERROR AT INIT EVERYTHING\n";
state = false;
}
}
SDL_Texture* interface::LoadTexture(const char* filename)
{
SDL_Surface* tempSurface = IMG_Load(filename);
if(!tempSurface)
{
std::cout<<"Eroare la imaginea: "<<filename<<SDL_GetError<<std::endl;
}
SDL_Texture* tex = SDL_CreateTextureFromSurface(renderer,tempSurface);
SDL_FreeSurface(tempSurface);
return tex;
}
void interface::DrawTexture(SDL_Texture* tex, SDL_Rect imgRect,SDL_Rect destRec)
{
SDL_RenderCopyEx(renderer,tex,&imgRect,&destRec,0,NULL,SDL_FLIP_NONE);
}
This is the code of mainClient.cpp where I include interface.h:
#include "client.h"
#include "interface.h"
int main()
{
client *Client = new client;
interface *screen = new interface(800,600);
screen->init("ReadsProfiler");
Client->init();
Client->loop();
}
I get the same error if I don't use client.h, so I'm not gonna add the code to that as well.

Because rendereris static, you also need to declare it in the .cpp file.
Add it to interface.cpp, for example under #include "interface.h":
SDL_Renderer* interface::renderer;

Related

Have X11 c program compiled, getting undefined reference errors, what lib(s) are needed?

I am new to c programming on Linux. My objective is to create an efficient program to monitor free space on a mounted partition (parm1) and put an icon in the tray to represent it showing my name (parm2) for it and the percentage of free space (script to calculate parm3), run that script every xxx seconds (parm4) and refresh the icon if the value changes (icon filename parm5).
For starters I have just copied a sample c program from here and am just trying to get it to compile and run as is, to embed a program with an icon in the tray.
freedesktop XEmbed systray client code in C, Xlib
I tweaked it to incorporate suggested changes and remove errors, and it compiles clean, but appears to need lib(s) added to be able to create an executable.
How do I find out what libraries are needed, and what order to put them in?
/* from: https://stackoverflow.com/questions/45392284/freedesktop-xembed-systray-client-code-in-c-xlib */
#include <X11/Xutil.h>
#include <string.h>
#include <unistd.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
/* --------- XEMBED and systray stuff */
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2
int usleep(useconds_t useconds); //pass in microseconds
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *, XErrorEvent *);
static int
error_handler(Display *display, XErrorEvent *error) {
trapped_error_code = error->error_code;
return 0;
}
void
trap_errors(void) {
trapped_error_code = 0;
old_error_handler = XSetErrorHandler(error_handler);
}
int
untrap_errors(void) {
XSetErrorHandler(old_error_handler);
return trapped_error_code;
}
void
send_systray_message(Display* dpy, long message, long data1, long data2, long data3) {
XEvent ev;
Atom selection_atom = XInternAtom (dpy,"_NET_SYSTEM_TRAY_S0",False);
Window tray = XGetSelectionOwner (dpy,selection_atom);
if ( tray != None)
XSelectInput (dpy,tray,StructureNotifyMask);
memset(&ev, 0, sizeof(ev));
ev.xclient.type = ClientMessage;
ev.xclient.window = tray;
ev.xclient.message_type = XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = message;
ev.xclient.data.l[2] = data1; // <--- your window is only here
ev.xclient.data.l[3] = data2;
ev.xclient.data.l[4] = data3;
trap_errors();
XSendEvent(dpy, tray, False, NoEventMask, &ev);
XSync(dpy, False);
usleep(10000);
if (untrap_errors()) {
/* Handle errors */
}
}
/* ------------ Regular X stuff */
int
main(int argc, char **argv) {
int width, height;
XWindowAttributes wa;
XEvent ev;
Display *dpy;
int screen;
Window root, win;
/* init */
if (!(dpy=XOpenDisplay(NULL)))
return 1;
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if(!XGetWindowAttributes(dpy, root, &wa))
return 1;
width = height = MIN(wa.width, wa.height);
/* create window */
win = XCreateSimpleWindow(dpy, root, 0, 0, width, height, 0, 0, 0xFFFF9900);
/* call send_systray_messsage */
send_systray_message(dpy, SYSTEM_TRAY_REQUEST_DOCK, win, 0, 0); // pass win only once
XMapWindow(dpy, win);
XSync(dpy, False);
/* run */
while(1) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev); /* just waiting until we error because window closed */
}
}
}
$ gcc xmbed_system_tray.c -o xmbed_system_tray
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `trap_errors':
xmbed_system_tray.c:(.text+0x3a): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `untrap_errors':
xmbed_system_tray.c:(.text+0x57): undefined reference to `XSetErrorHandler'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `send_systray_message':
xmbed_system_tray.c:(.text+0xa8): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xc2): undefined reference to `XGetSelectionOwner'
/usr/bin/ld: xmbed_system_tray.c:(.text+0xe8): undefined reference to `XSelectInput'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x131): undefined reference to `XInternAtom'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1ab): undefined reference to `XSendEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x1bf): undefined reference to `XSync'
/usr/bin/ld: /tmp/ccs2ZnYg.o: in function `main':
xmbed_system_tray.c:(.text+0x1f3): undefined reference to `XOpenDisplay'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x24f): undefined reference to `XGetWindowAttributes'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2b2): undefined reference to `XCreateSimpleWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2ed): undefined reference to `XMapWindow'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x2fe): undefined reference to `XSync'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x316): undefined reference to `XNextEvent'
/usr/bin/ld: xmbed_system_tray.c:(.text+0x322): undefined reference to `XPending'
collect2: error: ld returned 1 exit status
I didn't find any videos that showed anything, but I did find a site where he shows possible libraries or maybe locations. Therefore, I am guessing that either my environment is setup wrong so it can't find what it's looking for, or what it's looking for isn't installed.
http://mech.math.msu.su/~nap/2/GWindow/xintro.html
That didn't help, but I eventually found another page that did at:
https://en.wikibooks.org/wiki/X_Window_Programming/Xlib
Their sample program had compile instructions:
To Compile: gcc -O2 -Wall -o test test.c -L /usr/X11R6/lib -lX11 -lm
So for mine I tried:
gcc -o xmbed_system_tray xmbed_system_tray.c -lX11
By removing options one at a time I found the -lX11 parameter not being there before was causing the failure, and now the executable gets created and will run.
The program only consumes about 1 mb of memory compared to 25 to 35 mb for the other programs I found capable of running a program in the tray.

C++11 threads no matching function call

I am trying to make a threaded grabber for my OpenCV application. I am unable to figure out why this code doesn't compile. It gives me an error that I believe means that the function call is wrong. However, it is the exact same way how I start a thread using std::thread usually! I want to use std::thread to accomplish it because it will offer more platform-independent compatibility, so please don't tell me to use a platform-specific library. I also want this to be STL-based, so no Boost or DLib. In my main.cpp, I have a working thread application, the code below:
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <mutex>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#define read_failure_threshold 512
long grabbers_active = 0;
namespace dev
{
class grabber
{
private:
bool enabled = false;
std::mutex lock;
int capture_mode;
int capture_id;
unsigned long read_failures = 0;
std::string stream;
std::string grabber_name;
cv::Mat image;
public:
void grabber_t()
{
.......[unimportant code]........
}
grabber(std::string name, int captureMode, int captureId, std::string location)
{
.......[unimportant code]........
}
void start()
{
if(!enabled)
{
std::thread grabber_thread(grabber_t);
grabber_thread.detach();
}
enabled = true;
grabbers_active++;
}
cv::Mat getImage()
{
.......[unimportant code]........
}
};
}
[ERRORS:]
In file included from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/main.cpp:1:0:
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp: In member function ‘void dev::grabber::start()’:
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:119:52: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>)’
std::thread grabber_thread(grabber_t);
^
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:119:52: note: candidates are:
In file included from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:4:0,
from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/main.cpp:1:
/usr/include/c++/4.8/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (dev::grabber::*)(); _Args = {}]
thread(_Callable&& __f, _Args&&... __args)
^
/usr/include/c++/4.8/thread:133:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘void (dev::grabber::*&&)()’
/usr/include/c++/4.8/thread:128:5: note: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^
/usr/include/c++/4.8/thread:128:5: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘std::thread&&’
/usr/include/c++/4.8/thread:122:5: note: std::thread::thread()
thread() noexcept = default;
^
/usr/include/c++/4.8/thread:122:5: note: candidate expects 0 arguments, 1 provided
make[2]: *** [CMakeFiles/build.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/build.dir/all] Error 2
make: *** [all] Error 2
The error log is also at the end of the code. The only errors I am worried about are the threading ones. The other ones are simple fixes, but require me to have the threading working.
I am in Ubuntu, using g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2. I have C++0x enabled in my CMakeLists.txt. Everything works perfectly in there
My main objective is to figure out why I am getting this error. I have been googling and trying different tricks for many hours, but nothing is working!
Thanks in advanced for your help :)
Change that :
std::thread grabber_thread(grabber_t);
Into that :
std::thread grabber_thread(&grabber::grabber_t, this);
grabber_t is a reference to non-static member function, you need to pass its address, but &grabber_t can't work as you must explicitly qualify name of member function when taking its address, thus resulting in &grabber::grabber_t.

How my custom module on linux 3.2.28 can make a call to print_cpu_info?

I'm going to implement my custom module in which information for CPU is printed using print_cpu_info(). In order to call print_cpu_info(), I have included the needed header file, but it doesn't work. Here is my module.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/alternative.h>
#include <asm/bugs.h>
#include <asm/processor.h>
#include <asm/mtrr.h>
#include <asm/cacheflush.h>
extern struct cpuinfo_x86 boot_cpu_data;
int cpuinfox86_init(void)
{
print_cpu_info(&boot_cpu_data);
return 0;
}
void cpuinfox86_exit(void)
{
printk("good bye cpu\n");
}
module_init(cpuinfox86_init);
module_exit(cpuinfox86_exit);
MODULE_LICENSE("GPL");
After compiling this module, I get
make -C /lib/modules/3.2.28-2009720166/build SUBDIRS=/home/tracking/1031_oslab modules
make[1]: Entering directory `/usr/src/linux-3.2.28'
CC [M] /home/tracking/1031_oslab/module.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: "print_cpu_info" [/home/tracking/1031_oslab/module.ko] undefined!
CC /home/tracking/1031_oslab/module.mod.o
LD [M] /home/tracking/1031_oslab/module.ko
make[1]: Leaving directory `/usr/src/linux-3.2.28'
any idea?
"print_cpu_info" is not exported symbol, so it can not be used by modules. However, you can use "kallsyms_lookup_name", which is exported, to get the address of "print_cpu_info" and execute the function call using a function pointer.
static void* find_sym( const char *sym ) { // find address kernel symbol sym
static unsigned long faddr = 0; // static !!!
// ----------- nested functions are a GCC extension ---------
int symb_fn( void* data, const char* sym, struct module* mod, unsigned long addr ) {
if( 0 == strcmp( (char*)data, sym ) ) {
faddr = addr;
return 1;
}
else return 0;
};
// --------------------------------------------------------
kallsyms_on_each_symbol( symb_fn, (void*)sym );
return (void*)faddr;
}
static void (*cpuInfo)(struct cpuinfo_x86 *);
How to use it:
unsigned int cpu = 0;
struct cpuinfo_x86 *c;
cpuInfo = find_sym("print_cpu_info");
for_each_online_cpu(cpu)
{
c = &cpu_data(cpu);
cpuInfo(c);
}

Undefined reference to a function defined by me

When I call readTransition() function in readDPDA() function declaration I get linker error: undefined reference.
How can I use a function defined by me in another function's declaration ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void readTransitionRules(char * temp);
void readDPDA(char * filename);
int main()
{
// irrelevant
}
void readTransitionRules(char * temp)
{
char *tempToken;
tempToken=strtok(temp," ,:");
int i;
for(i=0; i<5; i++)
{
printf("%s",tempToken);
strtok(NULL," ,:");
}
}
void readDPDA(char * filename)
{
/*This function tries to open DPDA text file to read
states,alphabet,stack symbols and transition rules
of the DPDA that we will use as Word Checker. */
extern void readTransitionRules(char * temp);
char * temp;
FILE * readerForDPDA;
readerForDPDA = fopen(filename,"r");
if(readerForDPDA!=NULL)
{
fgets(temp,30,readerForDPDA);
if(temp[0]=='T')
{
readTransitionRule(temp);
}
}
else
{
}
}
In ReadDPDA you refer to a readTransitionRule and not a readTransitionRules as you have defined. You are missing the letter s.
You are calling readTransitionRule, but your function is named readTransitionRules.
You probably had a warning about implicit function declaration. Don't ignore warnings.

error LNK2001: unresolved external symbol __imp__Py_InitModule4

I'm trying to extend Python with C++. I'm using Visual C++ 2008 and Python 2.7. I have had a lot of problems building the .dll file, and finally when it seemed to be everything correct, I can't stop getting this error:
error LNK2001: unresolved external symbol _imp_Py_InitModule4
I know it isn't a linker error because I had this error before (it gave me the error but with all kind of Py_... functions) and I had resolved that.
I don't know if this is an important data but I have build python27_d.dll with VC++ 2008 too.
This is the code:
#include "Python.h"
#include <windows.h>
#include <string.h>
#include <tchar.h>
#include <stdlib.h>
#include <Aclapi.h>
struct file_perms {
char user_domain[2050];
unsigned long user_mask;
};
void lookup_sid ( ACCESS_ALLOWED_ACE* pACE, char user_domain[] ) {
char username[1024]="";
char domain[1024]="";
ULONG len_username = sizeof(username);
ULONG len_domain = sizeof(domain);
PSID pSID =(PSID)(&(pACE->SidStart));
SID_NAME_USE sid_name_use;
LPWSTR username1 = reinterpret_cast<LPWSTR>( username );
LPWSTR domain1 = reinterpret_cast<LPWSTR>( domain );
if (!LookupAccountSid(NULL, pSID, username1, &len_username, domain1, &len_domain, &sid_name_use)){
strcpy(user_domain, "unknown");
} else {
strcat(user_domain,domain);
strcat(user_domain,"\\");
strcat(user_domain,username);
}
}
void acl_info( PACL pACL, ULONG AceCount, file_perms fp[]){
for (ULONG acl_index = 0;acl_index < AceCount;acl_index++){
ACCESS_ALLOWED_ACE* pACE;
if (GetAce(pACL, acl_index, (PVOID*)&pACE))
{
char user_domain[2050]="";
lookup_sid(pACE,user_domain);
strcpy(fp[acl_index].user_domain,user_domain);
fp[acl_index].user_mask=(ULONG)pACE->Mask;
}
}
}
static PyObject *get_perms(PyObject *self, PyObject *args)
{
PyObject *py_perms = PyDict_New();
//get file or directory name
char *file;
if (!PyArg_ParseTuple(args, "s", &file))
return NULL;
//setup security code
PSECURITY_DESCRIPTOR pSD;
PACL pDACL;
//GetNamedSecurityInfo() will give you the DACL when you ask for
//DACL_SECURITY_INFORMATION. At this point, you have SIDs in the ACEs contained in the DACL.
LPWSTR file1 = reinterpret_cast<LPWSTR>( file );
ULONG result = GetNamedSecurityInfo(file1,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL,
&pDACL, NULL, &pSD);
if (result != ERROR_SUCCESS){ return NULL;}
if (result == ERROR_SUCCESS){
ACL_SIZE_INFORMATION aclSize = {0};
if(pDACL != NULL){
if(!GetAclInformation(pDACL, &aclSize, sizeof(aclSize),
AclSizeInformation)){
return NULL;
}
}
file_perms *fp = new file_perms[aclSize.AceCount];
acl_info(pDACL, aclSize.AceCount, fp );
//Dict
for (ULONG i=0;i<sizeof(fp);i++){
PyObject *domain = Py_BuildValue("s",fp[i].user_domain);
PyObject *user = Py_BuildValue("s",fp[i].user_mask);
PyDict_SetItem(py_perms,domain,user);
}
}
return py_perms;
};
static PyMethodDef fileperm_methods[] = {
{ "get_perms", get_perms, METH_VARARGS, "Execute a shell command." },
{ NULL, NULL, 0, NULL }
};
extern "C"
__declspec(dllexport)
void init_fileperm(void)
{
PyObject *m=Py_InitModule("fileperm",fileperm_methods);
return;
}
I'm working in Windows 7 64bits.
I know that Py_InitModule is deprecated for Python 3 but I'm working in Python27 (2.7.3 ).
Does someone know why I get this error?
Thanks!
I had the same problem.
If you're compiling a 64-bit pyd, make sure python27.lib is also 64-bit (same goes for compiling a 32-bit pyd with a 32-bit python27.lib).

Resources