I installed gnuplot using sudo yum install gnuplot on terminal. And I have a cpp file, it use gnuplot. I compile without error.On linking,the error occurs.
Compile : g++ -c plot.cpp
Link : g++ -o exe plot.o -lplot
Code :
int main()
{
FILE *pipe = popen("gnuplot -persist", "w");
// set axis ranges
fprintf(pipe,"set xrange [0:11]\n");
fprintf(pipe,"set yrange [0:]\n");
int b = 5;int a;
// to make 10 points
std::vector<int> x (10, 0.0); // x values
std::vector<int> y (10, 0.0); // y values
for (a=0;a<10;a++) // 10 plots
{
x[a] = a;
y[a] = 2*a;// some function of a
fprintf(pipe,"plot '-'\n");
// 1 additional data point per plot
for (int ii = 0; ii <= a; ii++) {
fprintf(pipe, "%d %d\n", x[ii], y[ii]); // plot `a` points
}
fprintf(pipe,"e\n"); // finally, e
fflush(pipe); // flush the pipe to update the plot
usleep(1000000);// wait a second before updating again
}
return 0;
}
Add a flag -L /where/ever/you/have/the/lib -lplotto specify where libplot.a resides, if you need that lib at all. From your code however it seems that you're just feeding data into gnuplot but don't link against any libplot.a.
Related
I am putting together a minimal example leveraging parallelism features in C++17/20 within Matlab MEX functions. I am able to compile and run the mex function from Matlab, but when I set the execution policy of my C++ STL function to "par" instead of "seq", Matlab gives a runtime linkage complaint. Code and error message follows:
test.m (Matlab top-level script):
vec_in = zeros(5);
coeff = 0.05;
vec_out = test_mex_gateway(vec_in, coeff);
test_mex_gateway.cpp (C++ interface to Matlab):
#include "mex.h"
extern void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff);
void mexFunction( int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[] )
{
// Check for proper number of input and output arguments
if( nrhs != 2 )
{
mexErrMsgTxt( "3 input arguments required: input_data, coeff" );
}
if( nlhs > 2 )
{
mexErrMsgTxt( "Too many output arguments." );
}
const mwSize *matlab_data_dims_in;
mwSize matlab_data_dims_out[1];
// Input Parameters
float *input_data = (float *) mxGetData(prhs[0]);
float coeff = mxGetScalar(prhs[1]);
// Get dimensions
matlab_data_dims_in = mxGetDimensions(prhs[0]);
const int vec_len = matlab_data_dims_in[1];
// Set output data dimension
matlab_data_dims_out[0] = vec_len;
// Output data
plhs[0] = mxCreateNumericArray(1, matlab_data_dims_out, mxSINGLE_CLASS, mxREAL);
float *output_data = (float *) mxGetData(plhs[0]);
test_execute(input_data, output_data, vec_len, coeff);
}
test_execute.cpp (This is where the actual C++ STL call is made):
#include <execution> // std::execution::*
#include <numeric> // std::exclusive_scan()
void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff)
{
std::exclusive_scan
(
std::execution::par, // std::execution::seq works here for Mex call, par does not
array_in,
array_in + vec_size,
array_out,
0.0f,
[coeff](float a, float b)
{
float ret = a + b + coeff;
return ret;
}
);
}
I also have a stand-alone main function to replace the Mex wrapper to do a pure C++ test, test_standalone.cpp:
#include <vector>
#include <iostream>
size_t VEC_NUM_ELEM = 10;
extern void test_execute(float *array_in, float *array_out, const size_t vec_size, const float coeff);
int main(int argc, char **argv)
{
if (argc != 2)
{
std::cout << "Try: " << argv[0] << "<coeff>" << std::endl;
return -1;
}
const float coeff = std::stof(argv[1]);
std::cout << "Coeff: " << coeff << std::endl;
float __attribute__ ((aligned (64))) *vec1_array = (float *)malloc(VEC_NUM_ELEM * sizeof(float));
float __attribute__ ((aligned (64))) *vec2_array = (float *)malloc(VEC_NUM_ELEM * sizeof(float));
for (unsigned i = 0; i < VEC_NUM_ELEM; i++)
{
vec1_array[i] = static_cast<float>(i);
}
test_execute(vec1_array, vec2_array, VEC_NUM_ELEM, coeff);
return 0;
}
Here is how I am building and linking, build.sh:
#!/bin/bash
rm *.o
rm *.exe
rm *.mexa64
cstd=c++17
gpp910=/home/m/compilers/bin/g++
tbblib=/home/m/reqs/tbb/lib/intel64/gcc4.8
echo "Building test_execute.cpp..."
$gpp910 -std=$cstd -I/home/m/reqs/tbb/include -L$tbblib -ltbb -Wl,rpath=$tbblib -c test_execute.cpp -fPIC
echo "Building test_standalone.cpp..."
$gpp910 -std=$cstd -L$tbblib test_execute.o test_standalone.cpp -o test_standalone.exe -ltbb
echo "Building test_mex_gateway.cpp..."
mex test_execute.o test_mex_gateway.cpp -L$tbblib -ltbb
The parallel STL calls has a requirement to link against the Intel TBB (Threading Building Blocks), so before I run Matlab to call test.m OR before I run my test_standalone.exe, I run:
export LD_LIBRARY_PATH=/home/m/reqs/tbb/lib/intel64/gcc4.8:$LD_LIBRARY_PATH
I also make sure to make the the C++ library associated with the version of GCC we built with available at runtime:
export LD_LIBRARY_PATH=/home/m/compilers/lib64:$LD_LIBRARY_PATH
When I run test_standalone.exe, everything behaves normally whether I have the execution policy set to "par" or "seq" on std::exclusive_scan. When run test.m, if "seq" was compiled, I can run with no errors. If "par" was compiled, Matlab complains at runtime about a linkage issue:
Invalid MEX-file 'test_mex_gateway.mexa64': test_mex_gateway.mexa64: undefined symbol:
_ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl
I suspect this was a function that was supposed to be linked from TBB, which I confirmed:
$ nm /home/m/reqs/tbb/lib/intel64/gcc4.8/libtbb.so.2 | grep baseEl
0000000000028a30 T _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl
000000000005ed70 r _ZN3tbb10interface78internal20isolate_within_arenaERNS1_13delegate_baseEl$$LSDA
I confirmed Matlab's LD_LIBRARY_PATH has the path I supplied in the above "export .." to this library.
I tried making sure my libraries came before the many Matlab-centric paths Matlab adds to LD_LIBRARY_PATH after it launches from the terminal.
I tried baking the path to the linked libraries via a -Wl,rpath=<path_to_tbb.so> passage to the linker.
After almost two days, I can't figure out why Matlab is having this very specific runtime issue, especially when the pure C++ version is not. Any help would be appreciated.
RHEL 7.9
Matlab R2020a
GCC 9.1.0
TBB (Intel Thread Building Blocks) 2020.3
It appears that Matlab comes with a version of libtbb.so included in its installation. From what I can tell, when launching a Mex file, Matlab will use its own libraries first, regardless of your LD_LIBRARY_PATH order. This is what was giving me runtime issues as a Mex file but not as a pure C++ file. Removing the libtbb.so from Matlab's installation directory allowed runtime linkage to find my version of libtbb, and I was able to run without errors. Thanks to Cris Luengo for pointing me in the right direction.
This question already has answers here:
MSVCP140D.dll missing, is there a way around? [closed]
(2 answers)
Closed 3 years ago.
So I have programmed a simple graphical snake game using SFML in visual studio 2015
and it runs perfectly on my main computer. And I thought that I should try it on my laptop. When running the program it gave me this error:
System error: The program can't start because MSVCP140D.DLL is missing from your computer. Try reinstalling the program to fix this problem
So I searched it in my computer and found it so I copied it on my laptop and then again I received another error which was:
Application error: The application was unable to start correctly (0xc000007b). Click OK to close the application.
I tried reinstalling the Microsoft Visual C++ Redistributable and still it didn't work. (BTW it is not a code problem and I have installed SFML correctly and used its libraries and bins without any problem). Your help would mean a lot to me. Thank you!
Here is my code:
//
GraphicalLoopSnakeGame.cpp :
Defines the entry point for
the console application.
//
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;
int N = 30, M = 20;
int size = 16;
int w = size*N;
int h = size*M;
int dir, num = 4;
struct Snake
{
int x, y;
} s[100];
struct Fruit
{
int x, y;
} f;
void Tick()
{
for (int i = num;i>0;--i)
{
s[i].x = s[i - 1].x;
s[i].y = s[i - 1].y;
}
if (dir == 0) s[0].y += 1;
if (dir == 1) s[0].x -= 1;
if (dir == 2) s[0].x += 1;
if (dir == 3) s[0].y -= 1;
if ((s[0].x == f.x) && (s[0].y == f.y))
{
num++; f.x = rand() % N; f.y = rand() % M;
}
if (s[0].x>N) s[0].x = 0; if (s[0].x<0) s[0].x = N;
if (s[0].y>M) s[0].y = 0; if (s[0].y<0) s[0].y = M;
for (int i = 1;i<num;i++)
if (s[0].x == s[i].x && s[0].y == s[i].y) num = i;
}
int main()
{
srand(time(0));
RenderWindow
window(VideoMode(w, h),
"Snake Game!");
Texture t1, t2, t3;
t1.loadFromFile("images/white.png");
t2.loadFromFile("images/red.png");
t3.loadFromFile("images/green.png");
Sprite sprite1(t1);
Sprite sprite2(t2);
Sprite sprite3(t3);
Clock clock;
float timer = 0, delay = 0.12;
f.x = 10;
f.y = 10;
while (window.isOpen())
{
float time = clock.getElapsedTime().asSeconds();
clock.restart();
timer += time;
Event e;
while (window.pollEvent(e))
{
if (e.type == Event::Closed)
window.close();
}
if (Keyboard::isKeyPressed(Keyboard::Left)) dir = 1;
if (Keyboard::isKeyPressed(Keyboard::Right)) dir = 2;
if (Keyboard::isKeyPressed(Keyboard::Up)) dir = 3;
if (Keyboard::isKeyPressed(Keyboard::Down)) dir = 0;
if (timer>delay) { timer = 0; Tick(); }
////// draw ///////
window.clear();
for (int i = 0; i<N; i++)
for (int j = 0; j<M; j++)
{
sprite1.setPosition(i*size, j*size); window.draw(sprite1);
}
for (int i = 0;i<num;i++)
{
sprite2.setPosition(s[i].x*size, s[i].y*size); window.draw(sprite2);
}
sprite3.setPosition(f.x*size, f.y*size); window.draw(sprite3);
window.display();
}
return 0;
}
You are using the debug visual studio runtime, if you want to try it on another computer you should recompile your code in release mode and make sure that the appropriate visual studio runtime redistributable is installed.
If you really need to run a debug executable on another machine you need to make sure you copy the correct runtime (32 or 64-bit according to how you've compiled your program), this can be found in C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Redist\MSVC\14.24.28127\debug_nonredist (at least for visual studio 2019, the exact path will be slightly different depending on your visual studio version, e.g. visual studio 2015 uses C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\redist\debug_nonredist).
As far as I'm concerned the PC is missing the runtime support DLLs for your program. I sugges you should download it from MS site and be sure there is no viruses: https://www.microsoft.com/en-US/download/details.aspx?id=48145
The application was unable to start correctly (0xc000007b). Click OK to close the application. Firstly I suggest to test whether there is a problem between your application and its dependencies using dependency walker.
And then the Error Code means: 0xC000007B STATUS_INVALID_IMAGE_FORMAT. I think that you trying to use 64-bit DLL with 32-bit application (or vice versa).
I just started using c++ bindings of libgpiod library and have problem with settings gpios. I know, that I can create long vector of values, and apply it in all at once, but I would like to be able to set their direction, and control them separately. How can I do that?
What I tried is this:
First: Working code with applying all values at once:
#include <gpiod.hpp>
int main(int argc, char **argv)
{
::gpiod::chip chip("gpiochip0");
auto lines = chip.get_all_lines();
::gpiod::line_request requestOutputs = {
argv[0],
::gpiod::line_request::DIRECTION_OUTPUT,
0
};
int value_to_be_set = 0xAAAAAAA ; //example value
::std::vector<int> values;
for (int i = 0; i < 32; i++)
{
values.push_back((value_to_be_set >> i) & 1UL);
}
lines.request(requestOutputs, values);
lines.release();
return EXIT_SUCCESS;
}
Second, my approach to do that I want:
#include <gpiod.hpp>
int main(int argc, char **argv)
{
::gpiod::chip chip("gpiochip0");
auto lines = chip.get_all_lines();
::gpiod::line_request requestOutputs = {
argv[0],
::gpiod::line_request::DIRECTION_OUTPUT,
0
};
lines.request(requestOutputs);
int value_to_be_set = 0xAAAAAAA; //example value
for (int i = 0; i < 32; i++)
{
// This does not set value :(
lines.get(i).set_value((value_to_be_set >> i) & 1UL);
}
lines.release();
return EXIT_SUCCESS;
}
I also could not find a simple C++ example to toggle a single GPIO line using the latest Raspberry PI libraries.
There is a multi-line example below but this is not what was originally asked:
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/tree/bindings/cxx
Below is an example that will cause GPIO17 to go high then low to create a single line output pulse.
// Use gpio drivers to toggle a single GPIO
// line on Raspberry Pi
// Use following commands to install prerequisites and build
// sudo apt install gpiod
// sudo apt install libgpiod-dev
// g++ -Wall -o gpio gpip.cpp -lgpiodcxx
#include <iostream>
#include <gpiod.hpp>
#include <unistd.h>
int main(void)
{
::gpiod::chip chip("gpiochip0");
auto line = chip.get_line(17); // GPIO17
line.request({"example", gpiod::line_request::DIRECTION_OUTPUT, 0},1);
sleep(0.1);
line.set_value(0);
line.release();
}
also don't forget to build with the flag -lgpiodcxx (for c++) or -lgpiod (for c)
I am trying to build a system allowing to execute arbitrary R code from a C++ application.
In orded to achieve that, the core of the method follows what is described here: http://www.hep.by/gnu/r-patched/r-exts/R-exts_121.html
This worked fine for any R code so far. However, I encoutered an issue with using ggplot. I try to send ggplot resulting graph to a png file. It works fine if done directly in a R console, but when I use my C++ interface, the resulting file is empty.
More precisely, the R code is organized as follows:
Load library ggplot2
Define some dummy data to be plotted.
Call png to create a graphics device.
Call ggplot.
Call dev.off() to close the graphics device.
When reduced to a minimal case, here is my code:
#include <QDebug>
#include <Rembedded.h>
#include <Rinternals.h>
#include <R_ext/Parse.h>
int main(int argc, char *argv[])
{
const char *argvrf[] = {"RConsole"};
int argcrf = sizeof(argvrf) / sizeof(argvrf[0]);
Rf_initEmbeddedR(argcrf, (char**)argvrf);
// Create some dummy data for a ggplot.
// For the purpose of this minimal example, R code is just directly defined as a QString here.
QString RScript = "library(\"ggplot2\") \n" ;
RScript += "id<-c(1,2,3,4,5) \n" ;
RScript += "names<-c(\"A\",\"B\",\"C\",\"D\",\"E\") \n" ;
RScript += "notes<-c(12,20,13,15,10) \n" ;
RScript += "df1<-data.frame(id,names,notes) \n" ;
// Define a file as graphicsDevice (adapt adress to your own filesystem)
RScript += "png(\"C:/Users/Evain/Desktop/tests/testggplot.png\", width=480, height=480, res=72) \n" ;
// Drawing the ggplot.
RScript += "ggplot(data=df1,aes(x=id,y=notes))+geom_line() \n" ;
// Closing the graphic device.
RScript += "dev.off() \n" ;
ParseStatus status;
SEXP cmdSexp, cmdexpr = R_NilValue;
int i, errorOccurred, retVal=0;
// Convert the command line to SEXP
PROTECT(cmdSexp = Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(cmdSexp, 0, Rf_mkChar(RScript.toLocal8Bit().data()));
cmdexpr = PROTECT(R_ParseVector(cmdSexp, -1, &status, R_NilValue));
switch (status){
case PARSE_OK: {
// Loop is needed here as EXPSEXP might be of length > 1
for(i = 0; ((i < Rf_length(cmdexpr)) && (retVal==0)); i++){
R_tryEval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv, &errorOccurred);
if (errorOccurred) {
// Interrupt process.
qDebug() << "Error occured" ;
retVal = -1;
}
}
break ;
}
default: {
qDebug() << "Incorrect R command" ;
break;
}
}
return 0;
}
Communication with R works fine if it is not a ggplot. For example, if I replace the
RScript += "ggplot(data=df1,aes(x=id,y=notes))+geom_line() \n" ;
With:
RScript += "plot(3) \n";
Then it works fine, a png file is create with the required plot.
With ggplot, this code runs without apparent issue. The qDebug() messages are not triggered. The png file is even created (meaning that the call to png() is executed correctly). But the file is empty.
It is not just an issue with the combination of png() and ggplot() or with my dummy data, since if I just launch the following R script in a R console, I get the expected result (the file is created and contains the plot):
library("ggplot2")
id<-c(1,2,3,4,5)
names<-c("A","B","C","D","E")
notes<-c(12,20,13,15,10)
df1<-data.frame(id,names,notes)
png("C:/Users/Evain/Desktop/tests/testggplot.png", width=480, height=480, res=72)
ggplot(data=df1,aes(x=id,y=notes))+geom_line()
dev.off()
Note: I'm on Windows 10, using R3.4.3.
It is worth noting that the png() method behaves slightly differently on Linux. For windows, the file is created when png() is called, even if it has to remain empty. For Linux, the file wouldn't be created if nothing is written in it.
If the png file already exist, it also gets replaced by an empty one. That's what we should expect when calling png() alone. It's just that the ggplot doesn't get added to it.
It feels like combining R_tryEval() with png() works fine. Combining png() with ggplot works fine, but combining R_tryEval() with png() and ggplot() doesn't. Any idea ?
I'm on Ubuntu 12.04 & had some boost fies already in /usr/include. I did a
sudo apt-get install libboost-all-dev
and that installed a lot of files too. I don't want to remove this boost and install from source as several other packages depend on the version from the ubuntu repos. This is the sample code I want to run :-
#include <iostream>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
typedef vector< double > state_type;
const double sigma = 10.0;
const double R = 28.0;
const double b = 8.0 / 3.0;
void lorenz( state_type &x , state_type &dxdt , double t )
{
dxdt[0] = sigma * ( x[1] - x[0] );
dxdt[1] = R * x[0] - x[1] - x[0] * x[2];
dxdt[2] = x[0]*x[1] - b * x[2];
}
int main()
{
const double dt = 0.01;
state_type x(3);
x[0] = 1.0 ;
x[1] = 0.0 ;
x[2] = 0.0;
stepper_euler< state_type > stepper;
stepper.adjust_size( x );
double t = 0.0;
for( size_t oi=0 ; oi<10000 ; ++oi,t+=dt )
{
stepper.do_step( lorenz , x , t , dt );
cout << x[0] << " " << x[1] << " " << x[2] << endl;
}
}
ON first compile g++ -o test test.cpp, it threw an error
/usr/include/boost/numeric/odeint.hpp permission denied
So I changed the file permission of all odeint files recursively using
sudo chmod -R +x odeint/
This time, it did not say permission denied but threw 400 lines of error as can be seen here -> error log from terminal
How do I compile it ? There are no install guides for odeint in the documentation or anywhere else
This part of boost seems to use C++11 features. Therefore you need to add either -std=c++0x or -std=c++11 to your compiler invocation.
The subsequent error test.cpp: In function ‘int main()’: test.cpp:30:5: error: ‘stepper_euler’ was not declared in this scope points you to another source of error: You forgot to include the file in which stepper_euler is declared. Put the appropriate #include <file> at the beginning of your code.