Has anyone been able to use libsensors properly? - c++

Long story short I am trying to write an application that can check cpu temperatures. Using the libsensors(3) man pages I've been able to at least get the libsensors_version number. As of now, here is my code:
#include <sensors/sensors.h>
#include "SensorData.h"
#include <string>
#include <sstream>
using namespace std;
SensorData::SensorData()
{
sensors_init(NULL);
}
SensorData::~SensorData()
{
sensors_cleanup();
}
string SensorData::GetVersion()
{
ostringstream Converter;
Converter<<"Version: "<<libsensors_version;
return Converter.str();
}
void SensorData::FetchTemp()
{
//sensors_get_value()
}
With the man pages I know that sensors_get_value expects
const sensors_chip_name *name
int subfeat_nr
double *value
to be passed to it. The problem is I have no idea what those are exactly. Just about every function in the documentation has this problem. They all expect vague things I don't know how to supply.
So here is the bulk of the question: Does anyone have any working examples of this library I could look at? Or at the very least does anyone know how to give these functions the values they need?
EDIT:
Since no one seems to know much about this library, does anyone know of a different way to get temperatures?

You can find out how to use the API by browsing the source code. The code for the sensors program isn't too complex to follow.
To get you started, here's a quick function that:
enumerates all the chips
enumerates all their features
prints the values of their readable subfeatures
You can just add it to your existing skeleton class as-is.
(This code is for demo purposes only, not tested thoroughly at all.)
void SensorData::FetchTemp()
{
sensors_chip_name const * cn;
int c = 0;
while ((cn = sensors_get_detected_chips(0, &c)) != 0) {
std::cout << "Chip: " << cn->prefix << "/" << cn->path << std::endl;
sensors_feature const *feat;
int f = 0;
while ((feat = sensors_get_features(cn, &f)) != 0) {
std::cout << f << ": " << feat->name << std::endl;
sensors_subfeature const *subf;
int s = 0;
while ((subf = sensors_get_all_subfeatures(cn, feat, &s)) != 0) {
std::cout << f << ":" << s << ":" << subf->name
<< "/" << subf->number << " = ";
double val;
if (subf->flags & SENSORS_MODE_R) {
int rc = sensors_get_value(cn, subf->number, &val);
if (rc < 0) {
std::cout << "err: " << rc;
} else {
std::cout << val;
}
}
std::cout << std::endl;
}
}
}
}

The Gnome panel Sensors applet works with libsensors (and other backends); the full sources are available from Sourceforge, here: http://sensors-applet.sourceforge.net/index.php?content=source
… in particular, the libsensors plug-in looks fairly legible… I believe this should be a usable gitweb link straight to that code: http://sensors-applet.git.sourceforge.net/git/gitweb.cgi?p=sensors-applet/sensors-applet;a=blob;f=plugins/libsensors/libsensors-plugin.c;h=960c19f4c36902dee4e20b690f2e3dfe6c715279;hb=HEAD

Your code should looks like this:
/* Read /etc/sensors.d to get the names or use code in above post */
std::string chip_name = "CHIP_NAME-*";
/* Here you get the path to the chip you want to read */
int rc;
sensors_chip_name name;
rc = sensors_parse_chip_name(chip_name.c_str(), &name);
/* Check rc != 0 */
/* Here you get the internal structure */
int nr = 0; //Here I silently assume you have only one chip to read
const sensors_chip_name* p_chip;
p_chip = sensors_get_detected_chips(&name, &nr);
/* Check p_chip != 0 */
/* Now you read the value - this you can repeat in some for/while cycle */
double val;
/* Replace the "1" with the feature you want to read */
rc = sensors_get_value(p_chip, 1, &val);
std::cout << "Now I can use sensors library " << val << std::endl;
Hope it helps despite the fact it is not copy/paste solution.
You can obtain the const sensors_chip_name* p_chip; from the code above post as well.
I believe the problem is in fact the const sensors_chip_name MUST be returned and filled by sensors library.

Related

How to use MPIR Prime testers mpz_likely_prime_p and mpz_probable_prime_p?

I'm trying to use MPIR's prime tester(s) for rapid non-sequential testing; however, I'm new to MPIR and am confused about their usage - specifically the "gmp_randstate_t" parameter used by the function. Here's what I've got so far:
#include<iostream> // used for cout
#include<mpir.h>
int main() {
mpz_t PrimeCanidate;
mpz_init(PrimeCanidate);
mpz_set_ui(PrimeCanidate, 3); // sets PrimeCanidate to unsigned int "3"
if (mpz_likely_prime_p(PrimeCanidate) == 1) {
std::cout << "Number is prime: " << std::endl;
}
}
As I'm only using one parameter inside mpz_likely_prime_p, it doesn't work - I just don't know what it's looking for with the other parameters (state, div) as shown in the documentation (http://www.mpir.org/mpir-3.0.0.pdf pg. 42):
Would anybody by chance have a simple code that uses the prime-testing functions in MPIR? Thanks a ton.
After a bunch of tinkering, I figured out how to properly initialize the "state" and div" parameters for mpz_likely_prime_p. Here's an example calculating and printing primes between 1 and 100:
#include<iostream> // used for cout
#include<mpir.h>
int main() {
mpz_t PrimeCanidate;
mpz_init(PrimeCanidate);
mpz_set_ui(PrimeCanidate, 2);
mpz_t additor;
mpz_init(additor);
mpz_set_ui(additor, 1);
gmp_randstate_t state;
gmp_randinit_default(state);
mpir_ui div = 0;
int maxbase = 100;
for (int base = 2; base < maxbase; base++) {
mpz_add(PrimeCanidate, PrimeCanidate, additor); // repeatedly adds one to PrimeCanidate
std::cout << "Tested Number: " << PrimeCanidate << std::endl;
if (mpz_likely_prime_p(PrimeCanidate, state, div) == 1) {
std::cout << PrimeCanidate << " is prime." << std::endl;
}
}
}
This is probably not optimal, but it works and might be a good place to start.

Converting DriverVersion to Human readable format

I have searched high and low for it, could not find any documentation, I am able to get the DriverVersion as described Here. Creating and enumerating the device drives is working so there is no need to look there. The DriverVersion is a type of "DWORDLONG". I need to convert this to Human readable format like 20.xx.xx.xx. There ain't any documentation on MSDN, or anywhere I have searched.
Any help will be appreciated.
Example value of "DriverVersion" : 1688863374327808
Code snippet, if at all its required,
SP_DEVINFO_DATA devInfo;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
if (SetupDiEnumDeviceInfo(handle, 0, &devInfo))
{
if(SetupDiBuildDriverInfoList(handle,&devInfo,SPDIT_COMPATDRIVER))
{
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
int i=0;
while(1)
{
try
{
if (SetupDiEnumDriverInfo(handle, &devInfo, SPDIT_COMPATDRIVER, i++, &drvInfo))
{
cout<<"Version :"<<drvInfo.DriverVersion<<endl; // Need Human Readable version here.
}
else
break;
}
catch(std::exception ex)
{
break;
}
}
}
}
You could use a ULARGE_INTEGER union, the HIWORD/LOWORD macros and string formatting utils like boost::format to do the following (untested code):
SP_DRVINFO_DATA driverInfoData;
ULARGE_INTEGER version;
version.QuadPart = driverInfoData.DriverVersion;
std::string versionStr = (boost::format("%s.%s.%s.%s")
% HIWORD(version.HighPart)
% LOWORD(version.HighPart)
% HIWORD(version.LowPart)
% LOWORD(version.LowPart)).str();
Following your code and to get rid of boost simply do:
std::cout << "Version: "
<< std::to_string(HIWORD(version.HighPart)) << "."
<< std::to_string(LOWORD(version.HighPart)) << "."
<< std::to_string(HIWORD(version.LowPart)) << "."
<< std::to_string(LOWORD(version.LowPart)) << std::endl;

Passing several datatypes from a function to main to create a class using pointers [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I would like to start this thread by thanking you for taking to the time to read my query.
I have created a function called retreiveFile which as you would expects retreives a file and reads from it. The text it reads is a set of numbers and text which represent names, cost and that sort of thing.
I have used istringstream to read through the file, determine the starting number(so I know what the line represents(property, card, ect)). Currently I have the file outputting the text but only with its corresponding data.
Example:
9 Oakmoor Road 80 5 0
9 Eldon Road 50 5 0
I need to know how I could pass this information into a class as I assume because I am going to have many objects of the same class I need to pass the data into main somehow.
(I tried creating the class using constructor within the function but it would not work)
I am assuming I would have to create pointers for the information, pass it to main, create the constructors and then delete the pointers.
My question to you would be how could I do this efficiently as I need to create around 30 objects which could fit in several different types of classes as some have different parameters.
I'm sorry in advance in some information seems vague or confusing I am still, in my head, trying to picture how I could do it.
An example of one of the ways I've separated the text within the file so I can easily pass it over to its correct class.
if (word[i].find("1") == 0){ //starts with 1
istringstream is(word[i]);
string aword;
int loopTimes = 0;
while (is >> aword) { // read each word from line
string propertyArray[6];
if (loopTimes == 0){
string stringIdentificationNum = aword;
/* const char * charIdentificationNum = stringIdentificationNum.c_str();
int identificationNum = atoi(charIdentificationNum); */
cout << "(1.1)" << aword;
propertyArray[0] = aword;
}
else if (loopTimes == 1){
cout << "(1.2)" << aword;
propertyArray[1] = aword;
}
else if (loopTimes == 2){
cout << "(1.3)" << aword;
propertyArray[2] = aword;
}
else if (loopTimes == 3){
cout << "(1.4)" << aword;
propertyArray[3] = aword;
}
else if (loopTimes == 4){
cout << "(1.5)" << aword;
propertyArray[4] = aword;
}
else if (loopTimes == 5){
cout << "(1.6)" << aword << endl;
propertyArray[5] = aword;
}
loopTimes++;
/* Property(propertyArray[0], propertyArray[1], propertyArray[2], propertyArray[3], propertyArray[4], propertyArray[5]); */
}
}
An example of the propertyClass
class Property : public Card{
private:
int identificationNum;
string propertyName;
int propertyCost;
int propertyRent;
int propertyColour;
public:
//constructor
Property::Property(int inputIdentificationNum, string inputFName, string inputSName, int inputCost, int inputPropertyRent, int inputPropertyColour){
setIdentificationNum(inputIdentificationNum);
setFirstName(inputFName, inputSName);
setPropertyCost(inputCost);
setPropertyRent(inputPropertyRent);
setPropertyColour(inputPropertyColour);
cout << "Property Created" << endl;
}
//set data
void setIdentificationNum(int inputIdentificationNum){
identificationNum = inputIdentificationNum;
}
void setFirstName(string inputFName, string inputSName){
string nameCombined = inputFName + " " + inputSName;
propertyName = nameCombined;
}
void setPropertyCost(int inputCost){
propertyCost = inputCost;
}
void setPropertyRent(int inputPropertyRent){
propertyRent = inputPropertyRent;
}
void setPropertyColour(int inputPropertyColour){
propertyColour = inputPropertyColour;
}
//retreive data
int getIdentificationNum() {
return identificationNum;
}
string getName(){
return propertyName;
}
int getPropertyCost(){
return propertyCost;
}
int getPropertyRent(){
return propertyRent;
}
int getPropertyColour(){
return propertyColour;
}
};
Thank you in advance for reading this thread.
Passing pointers around is unnecessary for this task and is actually frowned on. An objects data should stay locked up and hidden in the object unless you have a really good reason to expose it. In this case OP doesn't.
What follows cleans up OP's code and fixes some of the problems that made their attempt unworkable and probably lead them down the road to over-complicating things further.
Example is a container for a list of properties. Rather than passing around pointers to to the properties, OP can pass around references to Example and read the properties from example. This allows Example to defend itself from its clients. With a pointer to a property, a client could mistakenly change change a value that could result in breaking Example or another client of Example. With a Getter method, Example can control access to the properties with whatever grain is required.
Example, in this case, allows everyone to see properties, so long as the property exists, but does not allow changing the property.
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
class Example
{
private:
static constexpr size_t MAX_PROPERTIES = 6;
std::string propertyArray[MAX_PROPERTIES];
propertyArray is now a member variable and has scope that matches the object. Consider using a vector. It is not arbitrarily limited in size
public:
Example(std::stringstream & is)
{
std::string aword;
size_t looptimes = 0;
while (is >> aword && looptimes < MAX_PROPERTIES)
{
std::cout << "(1." << looptimes + 1 << ")" << aword << std::endl;
propertyArray[looptimes] = aword;
looptimes++;
This is where making propertyArray a vector really helps. You can use the push_back method to keep adding more and more properties. If you have a case with 8 properties in the future, it uses the exact same code as the 8 property version and you don't have to guard against overflow with the && looptimes < 6 in the while
}
}
std::string getProperty(size_t propertyNo)
New method used to get the properties for clients of Example. That way you don't have to pass around pointers to Example's data. Just pass around Example and if Example wants to give data, it can. No one can use an unprotected back door into Example to screw with Example's data without permission.
{
if (propertyNo < MAX_PROPERTIES)
{
return propertyArray[propertyNo];
}
throw std::out_of_range("Invalid property number");
}
};
And to test it out...
int main()
{
std::stringstream is ("A B C D E F G");
Example test(is);
try
{
std::cout << test.getProperty(4) << std::endl;
std::cout << test.getProperty(6) << std::endl;
}
catch (std::out_of_range & exc)
{
std::cout << exc.what() << std::endl;
}
}
Output:
(1.1)A
(1.2)B
(1.3)C
(1.4)D
(1.5)E
(1.6)F
E
Invalid property number
And now with a std::vector:
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <vector>
class Example
{
private:
std::vector<std::string> propertyArray;
public:
Example(std::stringstream & is)
{
std::string aword;
while (is >> aword)
{
propertyArray.push_back(aword);
std::cout << "(1." << propertyArray.size() << ")" << aword << std::endl;
}
}
std::string getProperty(size_t propertyNo)
{
if (propertyNo < propertyArray.size())
{
return propertyArray[propertyNo];
}
throw std::out_of_range("Invalid property number");
}
};
int main()
{
std::stringstream is ("A B C D E F G");
Example test(is);
try
{
std::cout << test.getProperty(4) << std::endl;
std::cout << test.getProperty(7) << std::endl;
}
catch (std::out_of_range & exc)
{
std::cout << exc.what() << std::endl;
}
}
Output:
(1.1)A
(1.2)B
(1.3)C
(1.4)D
(1.5)E
(1.6)F
(1.7)G
E
Invalid property number

how to get a value from a char[]

however,thanks everyone who help me.
I want to get the VmRSS value from /proc/pid/status,below is the code
int main()
{
const int PROCESS_MEMORY_FILE_LEN = 500;
FILE *file;
std::string path("/proc/4378/status");
//path += boost::lexical_cast<std::string>( pid );
//path += "/status";
if(!(file = fopen(path.c_str(),"r")))
{
std::cout <<"open " << path<<"is failed " << std::endl;
return float(-1);
}
char fileBuffer[PROCESS_MEMORY_FILE_LEN];
memset(fileBuffer, 0, PROCESS_MEMORY_FILE_LEN);
if(fread(fileBuffer, 1, PROCESS_MEMORY_FILE_LEN - 1, file) != (PROCESS_MEMORY_FILE_LEN - 1))
{
std::cout <<"fread /proc/pid/status is failed"<< std::endl;
return float(-1);
}
fclose(file);
unsigned long long memoryUsage = 0;
int a = sscanf(fileBuffer,"VmRSS: %llu", &memoryUsage);
std::cout << a << std::endl;
std::cout << memoryUsage << std::endl;
}
at last,thanks
Based on your comments: To find VmRSS within your char array use C++ algorithms in combination with the C++ string library. Then you'll get the position of VmRSS and all you'll have to do is to retrieve the wanted result. With a little knowledge of the structure of these entries, this should be an easy task.
In addition to that it might be better to use fstream for reading directly into a string.

Can someone provide an example of seeking, reading, and writing a >4GB file using boost iostreams

I have read that boost iostreams supposedly supports 64 bit access to large files semi-portable way. Their FAQ mentions 64 bit offset functions, but there is no examples on how to use them. Has anyone used this library for handling large files? A simple example of opening two files, seeking to their middles, and copying one to the other would be very helpful.
Thanks.
Short answer
Just include
#include <boost/iostreams/seek.hpp>
and use the seek function as in
boost::iostreams::seek(device, offset, whence);
where
device is a file, stream, streambuf or any object convertible to seekable;
offset is a 64-bit offset of type stream_offset;
whence is BOOST_IOS::beg, BOOST_IOS::cur or BOOST_IOS::end.
The return value of seek is of type std::streampos, and it can be converted to a stream_offset using the position_to_offset function.
Example
Here is an long, tedious and repetitive example, which shows how to open two files, seek to offstets >4GB, and copying data between them.
WARNING: This code will create very large files (several GB). Try this example on an OS/file system which supports sparse files. Linux is ok; I did not test it on other systems, such as Windows.
/*
* WARNING: This creates very large files (several GB)
* unless your OS/file system supports sparse files.
*/
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/positioning.hpp>
#include <cstring>
#include <iostream>
using boost::iostreams::file_sink;
using boost::iostreams::file_source;
using boost::iostreams::position_to_offset;
using boost::iostreams::seek;
using boost::iostreams::stream_offset;
static const stream_offset GB = 1000*1000*1000;
void setup()
{
file_sink out("file1", BOOST_IOS::binary);
const char *greetings[] = {"Hello", "Boost", "World"};
for (int i = 0; i < 3; i++) {
out.write(greetings[i], 5);
seek(out, 7*GB, BOOST_IOS::cur);
}
}
void copy_file1_to_file2()
{
file_source in("file1", BOOST_IOS::binary);
file_sink out("file2", BOOST_IOS::binary);
stream_offset off;
off = position_to_offset(seek(in, -5, BOOST_IOS::end));
std::cout << "in: seek " << off << std::endl;
for (int i = 0; i < 3; i++) {
char buf[6];
std::memset(buf, '\0', sizeof buf);
std::streamsize nr = in.read(buf, 5);
std::streamsize nw = out.write(buf, 5);
std::cout << "read: \"" << buf << "\"(" << nr << "), "
<< "written: (" << nw << ")" << std::endl;
off = position_to_offset(seek(in, -(7*GB + 10), BOOST_IOS::cur));
std::cout << "in: seek " << off << std::endl;
off = position_to_offset(seek(out, 7*GB, BOOST_IOS::cur));
std::cout << "out: seek " << off << std::endl;
}
}
int main()
{
setup();
copy_file1_to_file2();
}