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.
Related
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 !
Overview
I am writing a helper class to make calls to Redis easier with the xRedis drivers in C++, but I am continually receiving a segmentation fault upon requesting or sending any information to the instance.
I think this has to do with the way I'm storing the xRedis and RedisDBIdx instances, and possibly the way I'm storing the RedisAdmin instance within the main application, but I'm unable to see the right way to set these up after several attempts.
Relevant Code is below, and a few notes on debugging steps I have taken myself.
Debugging Notes
Redis Server is started successfully, and log output shows successful connection to server on instance startup
The call fails whether a set or exists command is sent to the server
GDB Output shows below, and logs show the same happenning on either exists or set calls:
Program received signal SIGSEGV, Segmentation fault.
RedisPool::GetConnection (this=0x0, cahcetype=0, dbindex=0, ioType=0) at src/xRedisPool.cpp:124
124 || (ioType>SLAVE)
Code
redis_admin.h
#include "xredis/xRedisClient.h"
#include <string.h>
#include <string>
class xRedisAdmin
{
xRedisClient xRed;
public:
xRedisAdmin(RedisNode conn_list[], int conn_list_size);
~xRedisAdmin();
const char * load ( const char * key );
bool save ( const char * key, const char * msg );
bool exists ( const char * key );
bool del ( const char * key );
};
redis_admin.cpp
xRedisAdmin::xRedisAdmin(RedisNode conn_list[], int conn_list_size)
{
enum {
CACHE_TYPE_1,
CACHE_TYPE_2,
CACHE_TYPE_MAX,
};
xRed.Init(CACHE_TYPE_MAX);
bool bret = xRed.ConnectRedisCache(conn_list, conn_list_size, CACHE_TYPE_1);
//Log results
}
//Exists
bool xRedisAdmin::exists(const char * key)
{
RedisDBIdx d(&xRedis);
char szKey[256] = {0};
sprintf(szKey, key);
return xRed.exists(d, szKey);
}
//Save
bool xRedisAdmin::save(const char * key, const char * val)
{
RedisDBIdx d(&xRed);
char szKey[256] = {0};
sprintf(szKey, key);
bool ret_val = xRed.set(d, szKey, val);
//Log output
return ret_val;
}
Main.cpp
xRedisAdmin *xRed;
void example_callback() {
bool bRet = xRed->save("key", "c_str");
}
int main()
{
xRedisAdmin x (RedisList1, conn_list_size);
xRed = &x;
example_callback();
return 0;
}
As it turns out, this is what I get for violating the Rule of Threes.
I did not have a copy constructor for the Redis Admin, and the xRed object inside it became null on assignment because of this. Use of new & delete, rather than creating in the main method, did resolve the issue. proved the solution to the issue
Thanks all who commented and gave me answers & support!
Alex
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.
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
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).