I am creating a wrapper class for working with sqlite3 in a command-line C++ application on my macbook. The database connection only works once after compilation.
First, the wrapper class (cmodel::dbpath is defined in another header, and I output it in the constructor to be sure):
class dbconnect {
sqlite3 *db;
const char *dbname;
public:
dbconnect();
~dbconnect();
};
dbconnect::dbconnect() :
dbname(cmodel::dbpath) {
// Output the path
std::cout << this->dbname << std::endl;
sqlite3_initialize();
// initialize this->db
int state = sqlite3_open_v2(this->dbname, &(this->db), SQLITE_OPEN_READWRITE, NULL);
if(state == SQLITE_OK) {
printf("Database opened successfully\n");
} else {
printf("%s\n", sqlite3_errmsg(this->db));
}
}
dbconnect::~dbconnect() {
std::cout << "Destructor called" << std::endl;
sqlite3_close_v2(this->db);
sqlite3_shutdown();
}
The main() function
int main() {
dbconnect db;
return 0;
}
And here is my prompt
$ make
g++ -lpthread -ldl ... /Users/awesomeuser/bin/cmodel
$ cmodel # first run
/Users/awesomeuser/.cmodel/cmodel.db
Database opened successfully
Destructor called
$ cmodel # second run
/Users/awesomeuser/.cmodel/cmodel.db
unable to open database file
Destructor called
To be honest, I'm not a big fan of these specific questions, but I'm just baffled. Any idea why this is happening?
UPDATE:
Ok here's something extra which is happening. When I open the db in the mode SQLITE_READWRITE | SQLITE_CREATE (which creates the database if it doesn't exist), a new database is created titled cmodel.XTUM in the same directory as cmodel.db. Does this sound familiar?
Related
I have a problem when I try to delete a file with Qt.
If I delete it with my Qt application in the same run as the file is created there is no issues, if I try to delete it when it already exists before the application has been launched, I receive an "access denied" issue.
Looking to this code:
int main(int argc, char *argv[])
{
QString path = "MyPath";
QFile file(path+"/test.txt");
if (file.open(QFile::ReadWrite)){
if(!file.setPermissions(QFileDevice::WriteUser | QFileDevice::ReadUser|
QFileDevice::ExeUser)){
std::cout << "Error in permissions" << std::endl;
}
file.close();
if(!QDir().remove(path+"/test.txt"))
std::cout << "Can't delete" << std::endl;
}
}
If I lanch the application, the file is created and then delete without any problem. If I try to access the file in Qt when it has already been created (by the application in a previous run, skipping the remove part of code) the file can't be delete or accessed.
I have tried to set the permissions but nothing has changed
After realizing it is nearly impossible to find help on getting keybindings to work with the C plugin in MPV (Possible to allow key bindings with MPV C API when no video (GUI) is being shown?), I decided to learn some Lua to help with the cause. Problem is, the docs aren't very clear on how to add Lua scripts with the C plugin, what I could find out was that check_error(mpv_set_option_string(ctx, "load-scripts", "yes")); should be called before initializing mpv in the C plugin, which points out that there should be a way to add scripts... When loading a script in the terminal you can do mpv video.mp4 --scripts="script_name.lua" and that will call the script from inside $HOME/.config/mpv... How do I achieve the calling of Lua scripts in the C plugin for MPV? I tried a few things including check_error(mpv_set_option_string(ctx, "scripts", "test.lua")); and check_error(mpv_set_property_string(ctx, "scripts", "test.lua")); and const char *cmd2[] = {"scripts", "test.lua", NULL}; check_error(mpv_command(ctx, cmd2));, none of which worked...
How do I call a Lua script for MPV from the C Plugin?
Below is the code I'm using to test things out:
// Build with: g++ main.cpp -o output `pkg-config --libs --cflags mpv`
#include <iostream>
#include <mpv/client.h>
static inline void check_error(int status)
{
if (status < 0)
{
std::cout << "mpv API error: " << mpv_error_string(status) << std::endl;
exit(1);
}
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
std::cout << "pass a single media file as argument" << std::endl;
return 1;
}
mpv_handle *ctx = mpv_create();
if (!ctx)
{
std::cout << "failed creating context" << std::endl;
return 1;
}
// Enable default key bindings, so the user can actually interact with
// the player (and e.g. close the window).
check_error(mpv_set_option_string(ctx, "input-default-bindings", "yes"));
mpv_set_option_string(ctx, "input-vo-keyboard", "yes");
check_error(mpv_set_option_string(ctx, "load-scripts", "yes"));
check_error(mpv_set_option_string(ctx, "scripts", "test.lua")); // DOES NOT WORK :(
int val = 1;
check_error(mpv_set_option(ctx, "osc", MPV_FORMAT_FLAG, &val));
// Done setting up options.
check_error(mpv_initialize(ctx));
// Play the file passed in as a parameter when executing program.
const char *cmd[] = {"loadfile", argv[1], NULL};
check_error(mpv_command(ctx, cmd));
// check_error(mpv_set_option_string(ctx, "scripts", "test.lua"));
check_error(mpv_set_option_string(ctx, "shuffle", "yes")); // shuffle videos
check_error(mpv_set_option_string(ctx, "loop-playlist", "yes")); // loop playlists
// check_error(mpv_set_option_string(ctx, "aspect", "0:0")); // set aspect
// Let it play, and wait until the user quits.
while (1)
{
mpv_event *event = mpv_wait_event(ctx, 10000);
std::cout << "event: " << mpv_event_name(event->event_id) << std::endl;
if (event->event_id == MPV_EVENT_SHUTDOWN)
break;
}
mpv_terminate_destroy(ctx);
return 0;
}
After playing around more with the mpv_set_property_string command, I discovered that you have to specify the FULL path to the Lua file, it by defaults searches for the file in the directory it is being played in, so if I tried to play it in /home/ it will search for /home/test.lua, so to get it to work I had to do check_error(mpv_set_property_string(ctx, "scripts", "/home/netsu/.config/mpv/test.lua")); (give the absolute path)
Recently I had alot of graphic driver issues, so today I used Display Driver Uninstaller to remove my Nvidia drivers and do a clean install. All good, but now when I try to compile one of my programs I get the following error:
"nvd3dum.pdb could not be found in the selected paths" (exception thrown)
What I tried so far:
reinstall the Nvidia drivers(again), since its a Nvidia file that should be the problem?
repair visual studio and update
download all symbols via windows server (Tools->Debugging->Symbols->Server)
I use the boost lib, SDL2(+image,audio,ttf,net),lua/c++ binding, its an "older" project created with VS2015
I tried another program(also SDL2), I get the same warning but it doesnt throw any exception and works fine.
Apparently the error is caused by a second thread:
LoadingScreen.start();
Stuff.Load(); //load SDLTextures
LoadingScreen.end();
//-----------
class LoadingScreen
{
public:
LoadingScreen();
void start() {
mIsActive = true;
mThread = std::thread(&LoadingScreen::render, this);
std::cout << "Start: Loading Screen" << std::endl;
}
void end() {
mIsActive = false;
mThread.join();
std::cout << "End: Loading Screen" << std::endl;
}
private:
void render()
{
while (mIsActive)
{
SDL_RenderClear(gRenderer);
mLoading.render(NULL,angle);
SDL_RenderPresent(gRenderer);
angle = angle + 1.25;
}
}
int mPercent;
std::thread mThread;
bool mIsActive = true;
DefaultTexture mLoading;
};
I have a problem with the example command plugin from the Maya 2013 API The code for the plugin have been split into a .h and a .cpp file for clarity, but should be otherwise correct.
pluginCmd.h:
// Include the needed headers.
#include <stdio.h>
#include <maya/MString.h>
#include <maya/MArgList.h>
#include <maya/MFnPlugin.h>
#include <maya/MPxCommand.h>
#include <maya/MIOStream.h>
// Class to represent our command.
class commandExample : public MPxCommand
{
public:
commandExample();
virtual ~commandExample();
MStatus doIt( const MArgList& );
MStatus redoIt();
MStatus undoIt();
bool isUndoable() const;
static void* creator();
};
pluginCmd.cpp:
// Include the header for the file.
#include "pluginCmd.h"
// Constructor for the command object.
commandExample::commandExample() {
cout << "In commandExample::commandExample()\n";
}
// Destructor for the command object.
commandExample::~commandExample() {
cout << "In commandExample::~commandExample()\n";
}
// The actual command/work to be performed.
MStatus commandExample::doIt( const MArgList& ) {
cout << "In commandExample::doIt()\n";
return MS::kSuccess;
}
// The creator is called when the command is invoked and sets up the command object.
void* commandExample::creator() {
cout << "In commandExample::creator()\n";
return new commandExample();
}
// Gets called when the plugin is loaded into Maya.
MStatus initializePlugin( MObject obj ) {
// Set plugin registration info: Author, plugin-version and Maya version needed.
MFnPlugin plugin( obj, "Martin Jørgensen", "1.0", "Any" );
plugin.registerCommand( "commandExample", commandExample::creator );
// Print to show plugin command was registered.
cout << "In initializePlugin()\n";
return MS::kSuccess;
}
// Gets called when the plugin is unloaded from Maya.
MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
plugin.deregisterCommand( "commandExample" );
// Print to show the plugin was unloaded.
cout << "In uninitializePlugin()\n";
return MS::kSuccess;
}
It is compiled successfully on Windows 7 x64 Visual Studio 12 with Maya 2013 x64 libraries.
When it is loaded in the plugin manager, noting happens (it should print the initialize status). But when It is unloaded, the initialize print shows up. Does anyone have a clue to why this is?
I'm having the same trouble when writing a plugin using Visual Studio 2015 and Maya 2016 x64.
The suggested workaround
cout << "Something out" << endl;
doesn't seem to work anymore.
I figured out that stuff written to cerr does show up in Maya's output window.
So as a temporary workaround I redirected cout to cerr:
cout.rdbuf(cerr.rdbuf());
Not ideal, but at least we get to see the output...
Tried using:
cout << "Something out" << endl;
as PeterT suggested in a comment, which works.
As a bonus I have realised that it did not "hang" when the command was called, it was because the command object was still active in the undo/redo history. This was a mistake in my ability to grasp Maya's workings.
Update 1: I have recently found out that WT communicates using TCP (HTTP), if that helps anyone.
The title says it all, is it possible to run 2 different WT applications or projects on the same port? I know WT has come control over how the application is hosted with its start up parameters as follows. I am using Visual Studio 2010 and the parameters below are entered in the debugging->command arguments box as follows:
--http-address=0.0.0.0 --http-port=8080 --deploy-path=/hello --docroot=.
The above parameters will require that the user opens a web page at
http://127.0.0.1:8080/hello
So I though, hey what if I host another project with the below parameters
--http-address=0.0.0.0 --http-port=8080 --deploy-path=/world --docroot=.
so then I would need to connect to
http://127.0.0.1:8080/world
The above actually does not work, it only hosts the first application that connects, and the second will not connect until the first shuts down. So this brings me here. Are there any other ways to run multiple WT applications on the same port?
Thank you in advance for any help!
Yes, you can achieve that but you will need to create your own WRun and use addEntryPoint. This is actually mentioned in the tutorial and goes as follows:
Inside WRun()
WRun() is actually a convenience function which creates and configures a WServer instance. If you want more control, for example if you have multiple “entry points”, or want to control the server starting and stopping, you can use the WServer API directly instead.
Here you have an example, both applications are the Hello World application, but notice that they have different titles and different messages on the buttons and when you press them. You can find another implementation of WRun on src/http/Serve.C and src/Wt/WServer.
two_helloworlds.cc
#include <Wt/WApplication>
#include <Wt/WBreak>
#include <Wt/WContainerWidget>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WText>
#include <Wt/WException>
#include <Wt/WLogger>
#include <Wt/WServer>
class HelloApplication : public Wt::WApplication
{
public:
HelloApplication(const Wt::WEnvironment& env, const std::string& title);
private:
Wt::WLineEdit *nameEdit_;
Wt::WText *greeting_;
void greet();
};
HelloApplication::HelloApplication(const Wt::WEnvironment& env, const std::string& title)
: Wt::WApplication(env)
{
setTitle(title);
root()->addWidget(new Wt::WText("Your name, please ? "));
nameEdit_ = new Wt::WLineEdit(root());
Wt::WPushButton *button = new Wt::WPushButton("Greet me.", root());
root()->addWidget(new Wt::WBreak());
greeting_ = new Wt::WText(root());
button->clicked().connect(this, &HelloApplication::greet);
}
void HelloApplication::greet()
{ greeting_->setText("Hello there, " + nameEdit_->text());
}
class GoodbyeApplication : public Wt::WApplication{
public:
GoodbyeApplication(const Wt::WEnvironment& env, const std::string& title);
private: Wt::WLineEdit *nameEdit_;
Wt::WText *greeting_;
void greet();
};
GoodbyeApplication::GoodbyeApplication(const Wt::WEnvironment& env, const std::string& title)
: Wt::WApplication(env)
{
setTitle(title);
root()->addWidget(new Wt::WText("Your name, please ? "));
nameEdit_ = new Wt::WLineEdit(root());
Wt::WPushButton *button = new Wt::WPushButton("Say goodbye.", root());
root()->addWidget(new Wt::WBreak());
greeting_ = new Wt::WText(root());
button->clicked().connect(this, &GoodbyeApplication::greet);
}
void GoodbyeApplication::greet()
{
greeting_->setText("Goodbye, " + nameEdit_->text());
}
Wt::WApplication *createApplication(const Wt::WEnvironment& env)
{
return new HelloApplication(env, "First app");
}
Wt::WApplication *createSecondApplication(const Wt::WEnvironment& env)
{
return new GoodbyeApplication(env, "Second app");
}
int YourWRun(int argc, char *argv[], Wt::ApplicationCreator createApplication, Wt::ApplicationCreator createSecondApplication)
{
try {
// use argv[0] as the application name to match a suitable entry
// in the Wt configuration file, and use the default configuration
// file (which defaults to /etc/wt/wt_config.xml unless the environment
// variable WT_CONFIG_XML is set)
Wt::WServer server(argv[0],"");
// WTHTTP_CONFIGURATION is e.g. "/etc/wt/wthttpd"
server.setServerConfiguration(argc, argv, WTHTTP_CONFIGURATION);
// add a single entry point, at the default location (as determined
// by the server configuration's deploy-path)
server.addEntryPoint(Wt::Application, createApplication);
server.addEntryPoint(Wt::Application, createSecondApplication,"/second");
if (server.start()) {
int sig = Wt::WServer::waitForShutdown(argv[0]);
std::cerr << "Shutdown (signal = " << sig << ")" << std::endl;
server.stop();
/*
if (sig == SIGHUP)
WServer::restart(argc, argv, environ);
*/
}
} catch (Wt::WServer::Exception& e) {
std::cerr << e.what() << "\n";
return 1;
} catch (std::exception& e) {
std::cerr << "exception: " << e.what() << "\n";
return 1;
}
}
int main(int argc, char **argv)
{
return YourWRun(argc, argv, &createApplication, &createSecondApplication);
}
Compile it with
g++ -g -o two_helloworlds two_helloworlds.cc -I/usr/local/include -L/usr/local/lib -lwthttp -lwt -lboost_random -lboost_regex -lboost_signals -lboost_system -lboost_thread -lboost_filesystem -lboost_program_options -lboost_date_time
and execute with
./two_helloworlds --docroot . --http-address 0.0.0.0 --http-port 8080
on localhost:8080 you will access one of the applications and on localhost:8080/second you will access the other.