I'm fairly new to C++ but this thing has me baffled by any logic. My code is as follows:
#include "stdlib.h"
#include "syslog.h"
#include "unistd.h"
#include "sys/stat.h"
#include "X11/Xlib.h"
#include "cstdio"
void process();
void startTracker();
Display *display;
Window rootWindow;
XEvent xevent;
I have the Xlib header included and if I click on member functions in Eclipse it navigates to the definitions.
int main(int argc, char *argv[])
{
// set logging up
openlog("unison", LOG_CONS|LOG_PID|LOG_NDELAY, LOG_LOCAL1);
syslog(LOG_NOTICE, "Starting Unison Handler");
pid_t pid, sid;
pid = fork();
// fork failed
if (pid < 0) {
exit(EXIT_FAILURE);
}
if (pid > 0) {
exit(EXIT_SUCCESS);
}
umask(0);
sid = setsid();
if (sid < 0) {
exit(EXIT_FAILURE);
}
if (chdir("/") < 0) {
exit(EXIT_FAILURE);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
startTracker();
while (true) {
process();
}
closelog();
return(EXIT_SUCCESS);
}
Then I assign the variables for input selection
void startTracker() {
display = XOpenDisplay(0);
rootWindow = XRootWindow(display, 0);
XSelectInput(display, rootWindow, PointerMotionMask);
}
void process()
{
...but when i add the &event here...
XNextEvent(display, &xevent);
switch (xevent.type) {
case MotionNotify:
syslog(
LOG_NOTICE,
"Mouse position is %dx%d",
xevent.xmotion.x_root, xevent.xmotion.y_root
);
}
}
...the whole thing falls apart.
For some reason passing the xevent as reference throws off the entire Xlib header and gives me this:
00:16:15 **** Incremental Build of configuration Debug for project unisond ****
make all
Building file: ../unisond.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"unisond.d" -MT"unisond.d" -o "unisond.o" "../unisond.cpp"
Finished building: ../unisond.cpp
Building target: unisond
Invoking: GCC C++ Linker
g++ -o "unisond" ./unisond.o
./unisond.o: In function `startTracker()':
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:97: undefined reference to `XOpenDisplay'
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:98: undefined reference to `XRootWindow'
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:99: undefined reference to `XSelectInput'
./unisond.o: In function `process()':
/home/ancarius/workspace/unisond/Debug/../unisond.cpp:105: undefined reference to `XNextEvent'
collect2: error: ld returned 1 exit status
make: *** [unisond] Error 1
00:16:15 Build Finished (took 159ms)
At the risk of getting downvoted could someone please explain what I've done wrong? I've tried everything I could think of but no luck.
It looks like you are missing the X11 library for linking.
add -lX11 to the g++ invocation.
This provides the steps required.
Right click on Project Folder> Properties> C/C++ Build > Settings > GCC C++ Linker > Libraries > add "X11"
Related
I'm trying to do my first bit of threading but no matter what I've tried I can't get this to compile.
I've gone back to trying to compile some demo code and I'm getting the same problem as in my program.
If I run a simple print hello world it compiles and deploys the program fine and I can simply navigate to and run it directly on the Pi4.
Threading demo code
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t tid[2];
void* doSomeThing(void* arg)
{
unsigned long i = 0;
pthread_t id = pthread_self();
if (pthread_equal(id, tid[0]))
{
printf("\n First thread processing\n");
}
else
{
printf("\n Second thread processing\n");
}
for (i = 0; i < (0xFFFFFFFF); i++);
return NULL;
}
int main(void)
{
int i = 0;
int err;
while (i < 2)
{
err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
i++;
}
sleep(5);
return 0;
}
When I compile I get
Error /home/pi/projects/cpp_raspbian_thread_101/obj/x64/Debug/main.o: in function `main':
Error undefined reference to `pthread_create'
Error ld returned 1 exit status
To resolve this I've tried to add -pthread or -lpthread to
Project > Properties > Configuration Properties > C/C++ > Command Line > Addiitional Options
That does nothing, I'm not really sure if this is the correct place to put this.
I'm building in VS2019 so I'm not building from the command line, I don't know where to add this argument.
I have also tried installing pthreads in NuGet but that doesn't help.
Other software like VSCode seem to have files that could add this to but I'm lost in VS2019
Any help is appreciated.
EDIT:
Thanks for responses
OK so as #Eljay suggested I'm trying to use std::thread (again) but have the same problem.
// thread example
#include <iostream>
#include <thread>
void foo()
{
// do stuff...
}
int main()
{
std::thread first(foo);
return 0;
}
Log file
Validating sources
Copying sources remotely to '10.0.0.2'
Validating architecture
Validating architecture
Starting remote build
Compiling sources:
main.cpp
Linking objects
/usr/bin/ld : error : /home/pi/projects/cpp_raspbian_thread_101/obj/ARM/Debug/main.o: in function `std::thread::thread<void (&)(), , void>(void (&)())':
/usr/include/c++/8/thread(135): error : undefined reference to `pthread_create'
collect2 : error : ld returned 1 exit status
So I'm back to the pthread_create problem again
OK both code examples now compile and run.
As I originally thought, I needed to add -pthread somewhere in VS2019 and I was putting it in the wrong section.
Go to
Project Properties > Configuration Properties > Linker > Command Line
Add -pthread to Additional Options box and Apply.
I hope that saves someone else the 3 days it took me to sort it!
I am using the <bcm2835.h> to connect on the GPIO of my Raspberry Pi. First I implemented a program in C and work perfectly. Now I am translating the same program to C++ and I am getting the error below when I try to start the <bcm2835.h>. My Eclipse IDE says /usr/local/lib/libbcm2835.a(bcm2835.o): relocation R_X86_64_32 against.rodata.str1.8' can not be used when making a shared object; recompile with -fPIConly when I use the functionbcm2835_init()`. I am already using -fPIC to generate the shared library.
class HCSR04r {
private:
int trigger;
int echo;
public:
HCSR04();
HCSR04(int trigger, int echo);
~HCSR04();
uint64_t cyclePulse(int trigger, int echo);
float distanceCentimeters();
};
#endif
#include <iostream>
#include <bcm2835.h>
#include "sensor/HCSR04.h"
HCSR04::HCSR04() {
this->echo = RPI_V2_GPIO_P1_13;
this->trigger = RPI_V2_GPIO_P1_15;
}
HCSR04::HCSR04(int trigger, int echo) {
this->echo = echo;
this->trigger = trigger;
}
HCSR04::~HCSR04() {
}
float HCSR04::distanceCentimeters() {
return (float) cyclePulse(trigger, echo) / 55.5;
}
uint64_t HCSR04::cyclePulse(int trigger, int echo) {
if (!bcm2835_init()) // THE ERROR IS BECAUSE THIS LINE
return 1;
uint64_t width;
//Close the bcm2835 bridge
bcm2835_close();
return width;
}
Now the error...
Building target: ../../../lib/libCommunicationLib.so
Invoking: GCC C++ Linker
g++ -shared -o "../../../lib/libCommunicationLib.so" ./code/utils/Metric.o ./code/sensor/GPS.o ./code/sensor/HCSR04.o ./code/sensor/ISensor.o ./code/CommunicationLib.o -lpthread -lbcm2835 -lgps
/usr/bin/x86_64-linux-gnu-ld: //usr/local/lib/libbcm2835.a(bcm2835.o): relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object; recompile with -fPIC
//usr/local/lib/libbcm2835.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [../../../lib/libCommunicationLib.so] Error 1
makefile:47: recipe for target '../../../lib/libCommunicationLib.so' failed
I have downloaded espeak-ng 1.1.49 and ./configure make make install it, and tested it by espeak --stdout "this is a test" | paplay successfully and it worked. Then I tried to use it inside my C++ code(testSpeak.cpp) that I found on the internet as you can see below:
#include <string.h>
#include <vector>
#include </usr/local/include/espeak-ng/speak_lib.h>
int samplerate; // determined by espeak, will be in Hertz (Hz)
const int buflength = 200; // passed to espeak, in milliseconds (ms)
std::vector<short> sounddata;
int SynthCallback(short *wav, int numsamples, espeak_EVENT *events) {
if (wav == NULL)
return 1; // NULL means done.
/* process your samples here, let's just gather them */
sounddata.insert(sounddata.end(), wav, wav + numsamples);
return 0; // 0 continues synthesis, 1 aborts
}
int main(int argc, char* argv[] ) {
char text[] = {"my name is espeak"};
samplerate = espeak_Initialize(AUDIO_OUTPUT_RETRIEVAL, buflength, NULL, 0);
espeak_SetSynthCallback(&SynthCallback);
espeak_SetVoiceByName("en");
unsigned int flags=espeakCHARS_AUTO | espeakENDPAUSE;
size_t size = strlen(text);
espeak_Synth(text, size + 1, 0, POS_CHARACTER, 0, flags, NULL, NULL);
espeak_Synchronize();
/* in theory sounddata holds your samples now... */
return 0;
}
But after trying to make executable by this command: g++ testSpeak.cpp -o speaks I got these error messages:
/tmp/ccR9O0vw.o: In function `main':
testSpeak.cpp:(.text+0x78): undefined reference to `espeak_Initialize'
testSpeak.cpp:(.text+0x90): undefined reference to `espeak_SetSynthCallback'
testSpeak.cpp:(.text+0x9c): undefined reference to `espeak_SetVoiceByName'
testSpeak.cpp:(.text+0xce): undefined reference to `espeak_Synth'
testSpeak.cpp:(.text+0xd2): undefined reference to `espeak_Synchronize'
collect2: error: ld returned 1 exit status
I know the problem is about linking but as I am new to Linux, don't know how can I fix it! Also I searched a lot but couldn't understand the solutions :(
I got it to compile correctly try installing
sudo apt-get install espeak-data libespeak-dev espeak-ng
your include is
#include </usr/local/include/espeak-ng/speak_lib.h>
make it
#include <espeak-ng/speak_lib.h>
your compile command is
g++ testSpeak.cpp -o speaks
try this one instead
g++ -W -o speaks myEspeak.cpp -lespeak
reference from i wouldn't compile it tough tried and it doesn't work probably an old version but with the code you provided and installing those programs and changing out your include your code will compile. I doesn't do much I would find a way to store that into a a .wav file.
http://apexlogic.net/code-bank/c-2/espeak-basic-usage-example/
when ever you compile from a shared library you need to link it with something that looks like
-lespeak
I'm learning how to use SFML, and after completing the RenderWindow tutorial with no problems, I've begun trying to use sf::Text and sf::Font with the next tutorial on the page.
Here is my code:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
int main() {
// initialise font
sf::Font ubuntu_r;
if(!ubuntu_r.loadFromFile("Ubuntu-R.ttf")) {
// unable to load font
std::cout << "Cannot load font." << std::endl;
}
// initialise text
sf::Text text;
text.setFont(ubuntu_r);
text.setString("Hello, world!");
text.setCharacterSize(50);
text.setColor(sf::Color(0x555555ff));
// initialise window
sf::RenderWindow win(sf::VideoMode(800,600),"Hello, world!");
// main loop
while(win.isOpen()) {
// check for closure
sf::Event e;
while(win.pollEvent(e)) {
if(e.type == sf::Event::Closed) {
win.close();
}
}
// draw text to screen
win.clear(sf::Color::White);
win.draw(text);
win.display();
}
return 0;
}
resulting in the following on compile:
$ g++ -c text.cpp
$ g++ text.o -o text -lsfml-graphics -lsfml-system -lsfml-window
text.o: In function `main':
text.cpp:(.text+0x10d): undefined reference to `sf::Font::loadFromFile(std::string const&)'
collect2: error: ld returned 1 exit status
This is very confusing, as I've checked in Font.hpp and loadFromFile() is definitely defined.
Commenting out all the text and font related code results in a perfectly compiled program that creates a white window that closes normally.
Probably the weirdest thing of all, however, is that if I selectively comment just the loadFromFile() bit:
#include <iostream>
#include <SFML/Graphics.hpp>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/Text.hpp>
int main() {
// initialise font
sf::Font ubuntu_r;
/*
if(!ubuntu_r.loadFromFile("Ubuntu-R.ttf")) {
// unable to load font
std::cout << "Cannot load font." << std::endl;
}
*/
// initialise text
sf::Text text;
text.setFont(ubuntu_r);
text.setString("Hello, world!");
text.setCharacterSize(50);
text.setColor(sf::Color(0x555555ff));
// initialise window
sf::RenderWindow win(sf::VideoMode(800,600),"Hello, world!");
// main loop
while(win.isOpen()) {
// check for closure
sf::Event e;
while(win.pollEvent(e)) {
if(e.type == sf::Event::Closed) {
win.close();
}
}
// draw text to screen
win.clear(sf::Color::White);
//win.draw(text);
win.display();
}
return 0;
}
this program compiles, runs with a white screen as before, but gives a segfault on close!
$ g++ -c text.cpp
$ g++ text.o -o text -lsfml-window -lsfml-system -lsfml-graphics
$ ./text
(I click close on the window)
Segmentation fault (core dumped)
What on earth is going on? Clearly the sf::Font isn't a problem as it compiles and runs fine with everything except loadFromFile().
I'm unsure about the segfault, because on this post the problems seem ever so slightly different to my own (it doesn't occur every time, for example). My initial thought is that the segfault is caused by the program trying to draw with an undefined font, but shouldn't that result in a runtime error as soon as the program is launched, and not only on closing the window?
Also, could this be related to this problem? My error message looks pretty different.
I'm using Ubuntu 16.04, compiling with gcc in terminal and writing the code in jEdit.
Given the following code:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int ac, char** av) {
int status;
pid_t cpid = fork();
if(0 == cpid) { /* Child */
return *(volatile int*) 0; /* exits with signal 11 */
} else { /* Parent */
do {
waitpid(cpid, &status, WUNTRACED);
if(WIFSIGNALED(status)) {
printf("\nChild exited with signal %d\n\n", WTERMSIG(status));
return 0;
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
printf("\nChild exited normally\n\n");
}
return 0;
}
I get the expected result running the app from Terminal:
$ ./Fork4GdbTests.exe
Child exited with signal 11
Running the app within LLDB (or GDB), strangely, I get:
$ lldb ./Fork4GdbTests.exe
(lldb) target create "./Fork4GdbTests.exe"
Current executable set to './Fork4GdbTests.exe' (x86_64).
(lldb) r
Process 46815 launched: './Fork4GdbTests.exe' (x86_64)
Child exited normally
Process 46815 exited with status = 0 (0x00000000)
My Makefile looks like this (used for Cygwin, also):
CC = gcc
CFLAGS = -Wextra -Wall -Werror -Wno-unused-parameter -g
.PHONY: all clean
all: Fork4GdbTests.exe
%.exe: %.o
$(CC) $(CFLAGS) $? $(LIBS) -o $#
clean:
rm -f *.o *.exe *.stackdump;
In Cygwin, I get the expected result both running from the command prompt and in the debugger. Similar behavior occurs for all kinds of other signals, such as SIGFPE or any signals sent to the child by means of kill().
What is going on?
That's just a bug. Given it affects both gdb & lldb it is probably in CoreOS not the debuggers (though the same folks did the Mach specific layer of both debuggers so that's not a guarantee...)
Anyway, please file a bug report with http://bugreporter.apple.com.