I am using Qt creator, and it generates this error:
"warning: format '%s' expects argument of type 'char*',
but argument 2 has type 'const void*' [-Wformat]"
The console app is working, but I am interested if there is way to avoid this error, just interested
#include <iostream>
#include <stdio.h>
using namespace std;
bool isOpen(FILE *file);
void print(const void *text);
#define FILE_IS_OPEN "The file is now open"
int main()
{
FILE *f;
f = fopen("This.txt", "w");
if(isOpen(f))
print(FILE_IS_OPEN);
fclose(f);
return 0;
}
bool isOpen(FILE *file) { return file != NULL ? true : false; }
void print(const void *text) { printf("%s\n", text); }
Simply change
void print(const void *text);
to
void print(const char *text);
The same applies in function definition.
Format specifier %s indicates that you're trying to output a string to console, so it requires you to give the address of the string which is nothing but char * here,
you can cast it to (char *)text and pass it to printf.
Also you can't output the contents of a void * pointer they have to any of the primitive data types.
Related
i tried the code shown below to call a c# dll function (COM) but when i do that i get the errors below "Invalid use of namespace 'MaxElementFn'"
My guess is that maybe i am calling the c# dll function incorrectly in c++ builder. any suggestion will be greatly appreciated. thank you in advance.
#include <Windows.h>
#include <cstdio>
using MaxElementFn = int(__stdcall *) (int a, int b);
int main()
{
HMODULE mod = LoadLibraryA("ExportedCodeSolution.dll");
MaxElementFn maxElement = reinterpret_cast<MaxElementFn>(GetProcAddress(mod, "maxElement"));
std::printf("max: %d\n", maxElement(1, 2));
}
[BCC32 Error] Unit1.cpp(145): E2070 Invalid use of namespace 'MaxElementFn'
[BCC32 Error] Unit1.cpp(151): E2451 Undefined symbol 'MaxElementFn'
these are the errors i am getting
// helper template
template<typename T>
bool GetFuncPointer(HMODULE module, const char* name, T& ptr)
{
ptr = (T)GetProcAddress(module, name);
if(!ptr) std::printf("function not found in dll: %s\n", name);
return ptr != nullptr;
}
// declare func pointer
int (__stdcall * maxElement) (int, int) = nullptr;
int main()
{
HMODULE mod = LoadLibraryA("ExportedCodeSolution.dll");
// make sure we actually have the function before calling
if(GetFuncPointer(mod, "maxElement", maxElement))
{
std::printf("max: %d\n", maxElement(1, 2));
}
return 0;
}
I am a somewhat rusty programmer, and new to C++. I've been asked to write a program that can pass a pointer to a function into another function and execute. I can make the simple case work, where everything is in a .cpp file. But when I place the code in a class inside a .h file it won't compile. I am either code blind or missing something.
Here is the code that works:
/*
* funcptr.cpp
*
* Example:
* - pass function pointer as argument
* - execute passed function
*/
#include <stdio.h>
void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);
// This function gets passed (to takes_a_function)
void print_char(void *data) {
char *ch = (char *)data;
printf("%c\n", *ch);
}
// This function gets passed (to takes_a_function)
void print_int(void *data) {
int *i = (int *)data;
printf("%d\n", *i);
}
void takes_a_function(void (*f)(void *), void *data) {
//f(data); // this also works
(*f)(data);
}
int main() {
int i = 100;
takes_a_function(print_int, &i);
char ch = 'A';
takes_a_function(print_char, &ch);
}
It compiles and runs:
# g++ funcptr.cpp -o funcptr
# ./funcptr
100
A
So far so good. But then I put the code into a .h file and "class"-ify it so I can use it from anywhere, and everything falls apart:
#ifndef __funcptr_h__
#define __funcptr_h__
#include <stdio.h>
void takes_a_function(void (*f)(void *data), void *data);
void print_char(void *data);
void print_int(void *data);
void testit();
class FunctionPtr
{
public:
// This function gets passed (to takes_a_function)
void print_char(void *data) {
char *ch = (char *)data;
printf("%c\n", *ch);
}
// This function gets passed (to takes_a_function)
void print_int(void *data) {
int *i = (int *)data;
printf("%d\n", *i);
}
void takes_a_function(void (*f)(void *a), void *data) {
//f(data); // this also works
(*f)(data);
}
void testit() {
int i = 100;
takes_a_function(print_int, &i);
char ch = 'A';
takes_a_function(print_char, &ch);
}
};
#endif
The compiler error is:
# g++ funcptr.h
funcptr.h: In member function ‘void FunctionPtr::testit()’:
funcptr.h:34:33: error: invalid use of non-static member function ‘void FunctionPtr::print_int(void*)’
takes_a_function(print_int, &i);
^
funcptr.h:22:7: note: declared here
void print_int(void *data) {
^~~~~~~~~
funcptr.h:37:35: error: invalid use of non-static member function ‘void FunctionPtr::print_char(void*)’
takes_a_function(print_char, &ch);
^
funcptr.h:16:7: note: declared here
void print_char(void *data) {
^~~~~~~~~~
I've been playing with this for a while and done a fair amount of reading on passing function pointers, including on StackOverflow, however all the examples I see are simple and of no help.
Any insights are much appreciated.
Thanks to all.
It looks to me like your problem is when you call takes_a_function with your arguments.
You declared the data parameter as a pointer to a void type, not a reference to a void type.
You could try something like:
void testIt() {
int i = 100;
int * j = &i;
takes_a_function(print_int, j);
char c = 'a';
char * d = &c;
takes_a_function(print_char, d);
};
References and pointers are not exactly the same thing.
Also it looks like you forgot a #endif after you define __funtptr_h__
I hope this helped
I'm trying to get my Arduino class to return String messages with all kind of information for logging. With lots of trial and error I manage to pass a reference to the logging function to the class, but can only get a char* but not a String, and I want to be able to send Strings making it so much easier to send back all kinds of data.
I have the first part working already.
The sketch:
#include <Test.h>
#include <string.h>
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
The header file:
#ifndef TEST_h
#define TEST_h
class Test
{
public:
Test(); // The constructor.
void setLogging(void (*)(char*)); // Takes function setting where to log.
void doSomething(char*);
};
#endif
The class:
#include <Test.h>
typedef void (*LogFunction)(char*);
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
void Test::setLogging (void (*f)(char*) ) {
writeLog = f;
return;
}
Now what I want my class to be able to do is send information like this, as String, rather than char* (I also haven't found an easy way of converting "anything" to char* and then concatenating the two or more strings):
writeLog ("HydroMonitorECSensor::setCalibration Receiving calibration - haveCalibration = " + String(haveCalibration));
writeLog ("HydroMonitorECSensor::setCalibration calibratedSlope = " + String(calibratedSlope));
writeLog ("HydroMonitorECSensor::setPins capPos set to " + String(capPos));
Where haveCalibration is a bool (which as String becomes either "true" or "false"), calibratedSlope is a double and capPos is an int. This way I can easily and cleanly send complete lines to the logger. Works great within the main script - not from the class.
I tried simply changing the char* to String and adding #include <string.h> to the library files but it doesn't work.
In Test.cpp I then get void Test::setLogging (void (*f)(String) ) { and in Test.h void setLogging(void (*)(String)); and now I get error messages:
In file included from /home/wouter/Arduino/libraries/Test/Test.cpp:1:0:
/home/wouter/Arduino/libraries/Test/Test.h:10:29: error: expected ',' or '...' before '(' token
void setLogging(void (*)(String)); // Takes function setting where to log.
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:40: error: variable or field 'setLogging' declared void
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:31: error: 'f' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
/home/wouter/Arduino/libraries/Test/Test.cpp:16:34: error: 'String' was not declared in this scope
void Test::setLogging (void (*f)(String) ) {
^
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).
Suggestions?
Additional info, maybe important: I'm using the Arduino IDE and compile for ESP8266.
You are using the Arduino-provided String class, but didn't include the Arduino.h header in your test.h header file. That causes it to not find the String class and compilation fails.
The following works:
main.cpp:
#include <Arduino.h>
#include <test.hpp>
void writeLog (char* message);
void writeLog (String message);
void setup() {
Serial.begin(115200);
Test t;
t.setLogging(writeLog);
writeLog("Test message!" + String(" .... "));
t.doSomething("This is useful.");
t.doSomething("This as well.\n");
t.doSomething("This is even more useful.\n");
bool b = true;
}
void loop() {
}
void writeLog (char* message) {
Serial.print("char function: ");
Serial.print(message);
}
void writeLog (String message) {
Serial.print("String function: ");
Serial.println(message);
}
test.hpp:
#ifndef TEST_h
#define TEST_h
#include <Arduino.h> //for "String" class
//Typdef for the log function. Takes a String, returns nothing
typedef void (*LogFunction)(String);
class Test
{
public:
Test(); // The constructor.
// void setLogging(void (*)(char*)); // Takes function setting where to log.
void setLogging(LogFunction); //use the typedef here
void doSomething(char*);
};
#endif
test.cpp:
#include <test.hpp>
LogFunction writeLog;
Test::Test () {
}
void Test::doSomething (char* s) {
// Do something useful and log the result.
writeLog(s);
}
//void Test::setLogging (void (*f)(char*) ) {
void Test::setLogging (LogFunction f) { //also use typedef here
writeLog = f;
return;
}
Among other things that may arise, the compiler tells you that it cannot resolve identifier String.
This can have several reasons: First, you write String, and not string (note the capital letter in your writing). Second, if you write string and not std::string, it cannot be resolved unless you have either declared using namespace std (which is not the preferred variant for several reasons) or using std::string. Third, class std::string is declared in header <string>, which is something different than <string.h>.
So I'd write #include <string> and use then std::string.
I have created a class that abstracts a SPI flash chip library called SerialFlash by creating an abstract class of Print.h. When I try to print to this by using the ArduinoJson library, I get an error:
src/FlashMemory.cpp:99:36: error: no matching function for call to 'ArduinoJson::JsonObject::printTo(<unresolved overloaded function type>)'
root.printTo(serialFlashPrint);
^
lib/ArduinoJson/include/ArduinoJson/Internals/../Internals/JsonPrintable.hpp:34:10: note: size_t ArduinoJson::Internals::JsonPrintable<T>::printTo(Print&) const [with T = Ardu
inoJson::JsonObject; size_t = unsigned int]
size_t printTo(Print &print) const {
^
lib/ArduinoJson/include/ArduinoJson/Internals/../Internals/JsonPrintable.hpp:34:10: note: no known conversion for argument 1 from '<unresolved overloaded function type>' to
'Print&'
The file referenced in the error above is here: https://github.com/bblanchon/ArduinoJson/blob/master/include/ArduinoJson/Internals/JsonPrintable.hpp
This is the header file for the class:
#include <Arduino.h>
#include <SerialFlash.h>
#include "Print.h"
#ifndef _SerialFlashPrint_h_
#define _SerialFlashPrint_h_
class SerialFlashPrint : public Print {
public:
SerialFlashPrint(SerialFlashFile *file);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *buffer, size_t size);
private:
char buf[1];
uint16_t _current_byte;
SerialFlashFile * _file;
};
#endif
And the cpp file:
#include "serialFlashPrint.h"
SerialFlashPrint::SerialFlashPrint(SerialFlashFile * file) : Print() {
this->_file = file;
this->_current_byte = 0;
}
size_t SerialFlashPrint::write(uint8_t c) {
if(_current_byte == 0){
_file->erase();
_file->seek(0);
}
sprintf(buf, "%c", c);
_file->write(buf, 1);
_current_byte++;
return 0;
}
size_t SerialFlashPrint::write(const uint8_t *buffer, size_t size){
_file->erase();
_file->seek(0);
_file->write(buffer, size);
_file->write(NULL, 1);
return 0;
};
Generally, you use print function as: the root.printTo(Serial). This code is based upon an abstraction (which I got to work previously) called Chunked output that can be seen here: https://github.com/bblanchon/ArduinoJson/wiki/Bag-of-Tricks
Does anyone have any clues for me to figure out why I am getting <unresolved overloaded function type> instead of Print&?
<unresolved overloaded function type> means that the compiler found a function with several overloads and doesn't know which one to use.
You most likely have several serialFlashPrint() in your code or libraries.
If not, then you may have triggered the Most vexing parse:
SerialFlashPrint serialFlashPrint; // <- creates an instance of SerialFlashPrint
SerialFlashPrint serialFlashPrint(); // <- declares a function returning a SerialFlashPrint
I have the following defined:
void LogMessage(PCTSTR text);
void LogMessage(PCTSTR format, ...);
If I just want to call the function with one parameter, I get the following error message:
Source.cpp(10): error C2668: 'Log' : ambiguous call to overloaded function
could be 'void Log(PCTSTR,...)' or 'void Log(PCTSTR)'
while trying to match the argument list '(const wchar_t [42])'
Is it possible to do a static_cast to explizite use the first version? Or haw can this be solved, except by renaming the first or second function?
How about the following? I haven't tested on VC++ (which seems to be your platform of choice) but hopefully the version you are using implements enough C++11 for this to work.
#include <iostream>
#include <cstdio>
#include <cstdarg>
void LogMessageWorker(char const* format, ...)
{
// 1k should be enough for anyone... ;)
char buf[1024] = { 0 };
// The version of vsnprint called should always null terminate correctly and doesn't
// strictly need the -1 but I believe that the implementation that is included with
// VC++ leaves a lot to be desired so you may need to slightly tweak this.
va_list args;
va_start (args, format);
vsnprintf (buf, sizeof (buf) - 1, format, args);
va_end (args);
std::cout << "LogMessage: " << buf << std::endl;
}
template <class... Arguments>
void LogMessage(char const* format, Arguments... arguments)
{
LogMessageWorker (format, std::forward<Arguments>(arguments)...);
}
void LogMessage(char const* text)
{
LogMessageWorker ("%s", text);
}
int main(int argc, char **argv)
{
LogMessage ("The test is starting...");
for (int i = 0; i < 3; i++)
LogMessage ("This is test #%d", i);
LogMessage ("This contains the % character and still it works (%d-%d-%d-%d)");
return 0;
}