Problem compiling C++ program after adding one argument to a function - c++

All I did was I added a single more argument (iterations) to this function:
/**
* saveImage : save the last image received.
* #param pName name of the file
*/
void GVMsample::saveImageLocal(const std::string& pName, const std::string& pImageFormat, const int &iterations) {
// Check that a video module has been registered.
if (!fRegisteredToVim) {
throw ALError(getName(), "saveImageLocal()", "No video module is currently "
"registered! Call registerToVIM() first.");
}
#ifdef GENERICVIDEOMODULE_IS_REMOTE_ON
// If this module is running in remote mode, we shouldn't use saveImageLocal.
throw ALError(getName(), "saveImageLocal()", "Module is run in remote mode, "
"use saveImageRemote instead !");
#else
ALImage* imageIn = NULL;
for ( int iter = 0; iter < iterations; iter++ )
{
// Now you can get the pointer to the video structure.
imageIn = (ALImage*) (fCamProxy->call<int>("getImageLocal", fGvmName));
if (!imageIn) {
throw ALError(getName(), "saveImageLocal", "Invalid image returned.");
}
fLogProxy->info(getName(), imageIn->toString());
// You can get some image information that you may find useful.
const int width = imageIn->fWidth;
const int height = imageIn->fHeight;
const int nbLayers = imageIn->fNbLayers;
const int colorSpace = imageIn->fColorSpace;
const long long timeStamp = imageIn->fTimeStamp;
const int seconds = (int)(timeStamp/1000000LL);
// Set the buffer we received to our IplImage header.
fIplImageHeader->imageData = (char*)imageIn->getFrame();
saveIplImage(fIplImageHeader, pName, pImageFormat, seconds);
// send image over UDP to the PC
// we will use udt
}
// Now that you're done with the (local) image, you have to release it from the V.I.M.
fCamProxy->call<int>("releaseImage", fGvmName);
#endif
}
The functions is defined like this in the header file:
/**
* saveImage : save the last image received.
* #param pName name of the file
*/
void saveImageLocal(const std::string& pName, const std::string& imageFormat, const int &iterations);
And I am getting this error:
When I take that argument away it compiles ok again.

As the error says, the prototype on line 51 of gvnsample.h is wrong. You forgot to update it, or you modified the wrong file.

Ok. I have figured out the problem. I was editing the right file. But...
I was editing the file in Windows 7 in a folder shared with Ubuntu 10.10. I was then trying to compile the program in Ubuntu through VirtualBox.
The problem was for some reason I need to reboot the virtual machine or else the files in the shared folder don't get updated when I rewrite them in Windows (when I rewrite a file in Ubuntu the changes are visible in Windows right away but the other way around reboot is needed - strange).

Related

ESP32 > using esp_console + argtable3 in a C++ project

I'am developping a C++ project on an ESP32.
I'd like to use esp_console + argtable3 (C libraries) in it.
I'm trying to use argtable3 in my members functions.
To do so, I'm creating callback functions to my members functions with a global pointer.
I'm sure my class is going to be instanced only once so I assume it's ok to create callback functions.
The problem is that argtable isn't giving me back the parameters entered by the user.
It checks for them successfully (number of args and their type) but the data it gives me back is random.
I've tested my code outside of members functions and it works well. But I want to use it inside members functions to access other parts of my object.
Here is my code :
// Pointer for my callback functions
MyClass * _callback;
struct arg_int *argInt;
struct arg_end *endPage;
// My callback function (GLOBAL)
int _setInt(int argc, char *argv[])
{
return _callback->setInt(argc, argv);
}
// Tab of struct for argtable lib (GLOBAL)
void *setInt_argtable[] =
{
argInt = arg_int1(NULL, NULL, "<0-12>", "Integer argument"),
endInt = arg_end(10)
};
// Function I'm calling back
int MyClass::setInt(int argc, char *argv[])
{
int nerrors = arg_parse(argc,argv,setInt_argtable);
if (nerrors > 0)
{
arg_print_errors(stdout, endPage, "myprog");
return 0;
}
printf("argc = %d\n", argc); // argc gives the correct number of args
printf("argv[0] = %s\n", argv[0]); // argv[0] gives the correct command name
printf("argv[1] = %s\n", argv[1]); // argv[1] gives the correct value
printf("argInt->ival[0] = %d\n", argInt->ival[0]); // argInt->ival[0] gives random value
return 0;
}
void MyClass::main(void)
{
// Callback pointer initialisation
_callback = this;
/* Initializing the console */
esp_console_config_t console_config
{
256,
8,
atoi(LOG_COLOR_CYAN),
0
};
ESP_ERROR_CHECK( esp_console_init(&console_config) );
/* Configure linenoise line completion library */
/* Enable multiline editing. If not set, long commands will scroll within
* single line.
*/
linenoiseSetMultiLine(1);
/* Tell linenoise where to get command completions and hints */
linenoiseSetCompletionCallback(&esp_console_get_completion);
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
/* Set command history size */
linenoiseHistorySetMaxLen(100);
esp_console_register_help_command();
//
// Feeding my console with argtable parameters
//
esp_console_cmd_t consoleCmd;
consoleCmd.command = "setInt";
consoleCmd.func = &_setInt;
consoleCmd.help = "Trying to set a integer argument";
consoleCmd.argtable = setInt_argtable;
esp_console_cmd_register(&consoleCmd);
/* Main loop */
while(true)
{
// Getting command from user
}
}
Is my approach of using callback member function good ?
Any idea of what is my problem and how I could solve it ?
Thanks in advance for your answers.
After being copying/pasting very simple sample codes found on internet, I finally found what was the problem :
I was including <argtable3/argtable3.h> after "myclass.h"
It took me almost 2 days for a dumb error...
But if somebody has an explanation about why the inclusion order was allowing me to compile the program but making a "corrupted" binary, feel free to answer !

how to call avformat_alloc_output_context2 in ffmpeg 2.6.3?

I'm developing an c/c++ app that uses ffmpeg to play audio/video.Now i want to enhance the application to allow the users to extract audio from video and save it. I followed this https://ffmpeg.org/doxygen/trunk/muxing_8c-source.html for the saving part but now the problem is with avformat_alloc_output_context2(). I'm getting an error: "undefined reference to `avformat_alloc_output_context2'
". Does anyone know about the proper way to call 'avformat_alloc_output_context2' in ffmpeg version 2.6.3
Remember to include
extern "C"
{
#include "libavformat/avformat.h"
}
After that you can just call
* #param *ctx is set to the created format context, or to NULL in
* case of failure
* #param oformat format to use for allocating the context, if NULL
* format_name and filename are used instead
* #param format_name the name of output format to use for allocating the
* context, if NULL filename is used instead
* #param filename the name of the filename to use for allocating the
* context, may be NULL
* #return >= 0 in case of success, a negative AVERROR code in case of
* failure
*/
int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, const char *format_name, const char *filename);
For example:
static const char* output_formats[] = { NULL, "mp3", "ogg", "wav" };
AVFormatContext* formatCtx = NULL;
QString outputFileName = "insert here your output file name";
avformat_alloc_output_context2(&formatCtx, NULL, output_formats[1], outputFileName.toStdString().c_str());
if(formatCtx == NULL)
{
//allocation have failed
}
Also git grep avformat_alloc_output_context2 in the in-source examples under doc/examples. A few matches:
https://github.com/FFmpeg/FFmpeg/blob/n3.0/doc/examples/remuxing.c#L79
https://github.com/FFmpeg/FFmpeg/blob/n3.0/doc/examples/muxing.c#L569
You can then see exactly how they are built with:
make V=1 examples
on the top-level. The build works on Ubuntu 15.10, so then you can compare it to your build and see what is wrong.

get hardware hard disk serial number with c++

I need to get the "real" hard disk serial number. I searched for different solutions without success.
I'm bulding a DLL in c++ that has to interact with another software/language.
Here's the code:
extern "C" __declspec(dllexport) void getHDSerial( int nParams, int* pIn, int* pOut )
{
char* command = "wmic path win32_physicalmedia get SerialNumber";
char* hdSerial = (char*) system(command);
if (hdSerial) {
GETSTRING(pOut[0]) = hdSerial;
// system(exit);
}
else {
GETSTRING(pOut[0]) = "1";
}
}
The DLL should reply the correct serial code as available in CMD using:
wmic path win32_physicalmedia get SerialNumber
No need to support for other OS, only windows.

Trying to open up a url address with an executable

I'm trying to open a user input url using ShellExecute in my c++ project but am finding difficulty in creating a main function within the project.
Currently I have
#include<Windows.h>
#include<stdlib.h>
#include<shellApi.h>
int findIE(const char*);
int main()
{
const char* url;
findIE(url);
return 0;
}
/**
* Open the default browser to the specified URL.
*
* \param url WebAddress to open a browser to.
*
* \returns
* If the function succeeds, it returns a value greater than 32.
* Otherwise,it returns an error code as defined in the ShellExecute documentation.
*
* \remarks
* The function uses the headerfiles: windows.h, stdlib.h, shellapi.h.
* The url is converted into a unicode string before being used.
**/
int findIE(const char* cUrl)
{
ShellExecute(NULL, "open", cUrl, NULL, NULL, SW_SHOWDEFAULT);
return 0;
}
I try going to my executable and running it but nothing is showing up...Can I get some advice on my next steps?
The program should be run:
findIE.exe websitename.com
Then open up the default browser to websitename.com
Thanks for responding!
The program should be run:
findIE.exe websitename.com
Ah, then you need to pass command line arguments to main.
At the very least:
int main( int argc, char ** argv )
{
if ( argc >= 2 )
{
findIE( argv[1] );
}
return 0;
}
You need to initialize the variable 'url'.
for example:
int main()
{
const char* url = "www.google.com"
findIE(url);
return 0;
}
And if you want to use user input you will have to take the constness of the char variable away.

spidermonkey 1.8.5 crashes in debug mode

I am using Spidermonkey 1.8.5 in my application.
My application crashes when I use the debug JS library. I am building the library with the following options:
--enable-debug --disable-optimize --enable-threadsafe
crash is pointing here:
Assertion failure: (cx)->thread->data.requestDepth || (cx)->thread == (cx)->runtime->gcThread, at ../../src/jsapi.cpp
Here is the sample program
/* Include the JSAPI header file to get access to SpiderMonkey. */
#include "jsapi.h"
/* The class of the global object. */
static JSClass global_class = {
"global", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS
};
/* The error reporter callback. */
void reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
fprintf(stderr, "%s:%u:%s\n",
report->filename ? report->filename : "<no filename=\"filename\">",
(unsigned int) report->lineno,
message);
}
int main(int argc, const char *argv[])
{
/* JSAPI variables. */
JSRuntime *rt;
JSContext *cx;
JSObject *global;
printf("Started\n");
/* Create a JS runtime. You always need at least one runtime per process. */
rt = JS_NewRuntime(8 * 1024 * 1024);
if (rt == NULL)
return 1;
/*
* Create a context. You always need a context per thread.
* Note that this program is not multi-threaded.
*/
cx = JS_NewContext(rt, 8192);
if (cx == NULL)
return 1;
JS_SetErrorReporter(cx, reportError);
/*
* Create the global object in a new compartment.
* You always need a global object per context.
*/
global = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL);
if (global == NULL)
return 1;
/*
* Populate the global object with the standard JavaScript
* function and object classes, such as Object, Array, Date.
*/
if (!JS_InitStandardClasses(cx, global))
return 1;
/* Your application code here. This may include JSAPI calls
* to create your own custom JavaScript objects and to run scripts.
*
* The following example code creates a literal JavaScript script,
* evaluates it, and prints the result to stdout.
*
* Errors are conventionally saved in a JSBool variable named ok.
*/
char *script = "'Hello ' + 'World!'";
jsval rval;
JSString *str;
JSBool ok;
const char *filename = "noname";
uintN lineno = 0;
ok = JS_EvaluateScript(cx, global, script, strlen(script),
filename, lineno, &rval);
if (rval == NULL | rval == JS_FALSE)
return 1;
str = JS_ValueToString(cx, rval);
printf("%s\n", JS_EncodeString(cx, str));
/* End of your application code */
/* Clean things up and shut down SpiderMonkey. */
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);
JS_ShutDown();
return 0;
}
If I am building in release mode the program works fine. this problem is only with the debug mode. What am I missing here?
Insert JS_BeginRequest(cx); just before the JS_NewCompartmentAndGlobalObject call.
Insert JS_EndRequest(cx); just before the call to JS_DestroyContext.
Most JSAPI functions require a request. (I'm not sure why. The original reason for threads had to do with multithreading, but each JSRuntime is single-threaded now.)
The debug build of SpiderMonkey includes assertions that check API usage in ways that release mode can't. So you will likely see debug-only assertions again. I strongly recommend developing against a debug build, because those assertions almost always indicate real problems.
The next SpiderMonkey release is coming soon: https://bugzilla.mozilla.org/show_bug.cgi?id=735599#c54