I am trying to intercept open system call in Linux. It works fine with other libraries but doesn't wotk with boost libboost_fileystem. Here is my code (stripped down for readability).
#include <boost/filesystem/fstream.hpp>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
using namespace boost::filesystem;
typedef int (*open_func_type)(const char * pathname, int flags, ...);
int open(const char *path, int flags, ...)
{
va_list arg;
mode_t mode = 0;
if (flags & O_CREAT)
{
va_start(arg, flags);
mode = va_arg(arg, mode_t);
va_end(arg);
}
//some stuff here
open_func_type open_func = (open_func_type) dlsym(RTLD_NEXT, "open");
return open_func(path, flags, mode);
}
int main()
{
boost::filesystem::fstream build_path;
build_path.open("/tmp/test.txt", ios::in);
//other stuff
return 0;
}
I stepped though the code using gdb, my open implementation doesn't get called. But doing strace shows the open system call being called. If I call other library functions that call open, I see my implementation getting called. Anything that I am doing wrong here? I am dynamically linking with boost libraries.
I gave sometime to figure it out and found that internally boost calls std::basic_filebuf open which in turn calls fopen. fopen seems to call open system call in the kernel without calling open library call (it would be nice if somebody could point it out why). I intercepted fopen call and this works fine now. If large file support is used, fopen64 also needs to be implemented.
Related
I found it a little tricky that some compiler can't run the <windows.h> header file. Is it possible to open an URL in C++ without using <windows.h> ?
Here's my code, but using <windows.h>
#include <windows.h>
#include <shellapi.h>
using namespace std;
int main(){
ShellExecute(NULL,NULL,"https://ssur.cc/Easy-Way-To-Open-URL-In-CPP",NULL,NULL,SW_SHOW );
return 0;
}
You could just forward declare the function in question and let the linker handle it.
But if your compiler has issues with windows.h it will probably not support all Windows platforms/architectures. But assuming the calling-convention used by the compiler just happens to match you can do something like this:
typedef void* M_HINSTANCE;
typedef void* M_HWND;
#define M_SW_SHOW 5
// should be __stdcall , but if your compiler has trouble with windows.h, then it will probably also have trouble with __stdcall
extern "C" M_HINSTANCE ShellExecuteA(M_HWND hwnd,
const char* lpOperation,
const char* lpFile,
const char* lpParameters,const char* lpDirectory,
int nShowCmd
);
int main(){
ShellExecuteA(0,0,"https://ssur.cc/Easy-Way-To-Open-URL-In-CPP",0,0,M_SW_SHOW );
return 0;
}
You will still need to link to Shell32.lib and like I mentioned you might get linker errors on some platforms for mismatching calling conventions.
Alternatively you can try to start the shell as a generic process like
#include <cstdlib>
int main(){
std::system("cmd.exe /c start https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
// or something like:
// std::system("explorer.exe https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
// or on some other non-windows platforms:
// std::system("open https://ssur.cc/Easy-Way-To-Open-URL-In-CPP");
return 0;
}
In an attempt to incorporate a windows platform feature into an otherwise crossplatform application, I've made a one-function VC++ DLL in visual studio that uses Windows.Management.Deployment.PackageManager to get some details on all installed windows store apps.
The function works fine as a standalone application, and I can successfully build the DLL with MSVC that links properly with my MinGW main application (I can happily return primitive data from the dll, etc) - but any attempt to execute a function from the dll containing code relating to PackageManager crashes my application in runtime with the unhelpful code -529697949.
Here's some minimal code blocks that replicate:
main.cpp in the main application:
#include <QCoreApplication>
#include "mylib/WindowsAppsLib.h"
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
auto hi = (Helpers::sayHi());
qDebug() << (hi);
return a.exec();
}
dll header:
#pragma once
#define WINDOWSAPPSLIB_API __declspec(dllexport)
namespace Helpers
{
extern "C" WINDOWSAPPSLIB_API const char* sayHi();
}
dll source:
#include "stdafx.h"
#include <sddl.h>
#include <collection.h>
#include "WindowsAppsLib.h"
#include <windows.h>
#using <Windows.winmd>
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace std;
const char* Helpers::sayHi()
{
auto packageManager = ref new Windows::Management::Deployment::PackageManager();
auto packages = packageManager->FindPackages();
return "Hi!";
}
Without the two lines relating to packagemanger, the program runs fine and prints "Hi!". When included, the program crashes with code -529697949 as soon as sayHi() is called. The two lines in themselves have their dependencies available and don't cause exceptions.
Any clues on how I might proceed to investigate this? Nothing I've been able to get out of this system is getting me closer to identifying the problem. Is this the sensible way to access Windows.Management.Deployment.PackageManager from within a plain C++ MinGW application to begin with?
I want to use Glog lib to log my application logs. My application is multithreaded. As Suggested in glog i have supposed to use RAW_LOG for thread safety. Here is my example code.
#include "stdafx.h"
#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <windows.h>
#include <glog/logging.h>
#include <glog/raw_logging.h>
using namespace std;
int main(int /*argc*/, char** argv)
{
FLAGS_alsologtostderr = 1;
google::SetLogDestination(google::GLOG_INFO, "E:/mylog.log");
google::InitGoogleLogging(argv[0]);
//LOG(INFO) << "Infomration";
RAW_LOG_INFO("Test");
RAW_LOG(INFO,"This is INFO");
RAW_LOG(WARNING,"This is WARNING");
RAW_LOG(ERROR, "This is Error");
return 0;
}
But log files are not generating if I use RAW_LOG but if I use LOG() function then log file is generating.
Please let me know how do I use RAW_LOG function or is LOG() function is threadsafe or not.
this is from the raw_logging.h
// * it logs straight and ONLY to STDERR w/o buffering
It can only log to stderr and is only for debugging purposes in low level code
so RAW_LOG(INFO,"...") will never generate any log files.
#include <stdio.h>
#include <windows.h>
using namespace std;
int main() {
char s[] = "Hello\n";
HANDLE stdout = GetStdHandle(STD_OUTPUT_HANDLE);
unsigned long cChars;
WriteConsole(stdout, s, lstrlen(s), &cChars, NULL);
}
result: error: declaration of '_iob' as array of references
but when I comment out stdio.h, it compiles ok. What's wrong here ?
Compiler is MinGW.
Depending on the platform, stdout is probably a macro, so better not use that name. Replace
HANDLE stdout = ...
with
HANDLE out = ...
and then
WriteConsole(out, ...
stdout is defined in stdio.h, that's why it fails only when this file is included. But to be safe, never use that name for any self-defined variable.
the stdout is already defined by system.. try changing it to _stdout or something else
I am trying to use ffmpeg library on windows in C++/Qt. This is my main function:
#include <iostream>
#include <stdio.h>
#include <math.h>
using namespace std;
#define INT64_C(val) val##LL
#define UINT64_C(val) val##ULL
#include <QtCore>
#include <SDL/SDL.h>
#ifdef __MINGW32__
#undef main
#endif
//--------------- FFMPEG Headers and Libraries ---------------
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
int main(int c, char *args[])
{
av_register_all();
AVFormatContext *ctx;
if(avformat_open_input(&ctx,"salam.avi",NULL,NULL)!=0)
return -1;
return 0;
}
It gets compiled & linked fine. But I get this error when I try to run it:
The program has unexpectedly finished
This happens on *avformat_open_input* function. What's the problem? Is it about my code, or it is a problem with my libraries?
Thanks in advance
Finally I found it. The answer is so simple. ctx should be initialized by NULL.
AVFormatContext *ctx = NULL;
Could be a problem with the AVI. Make sure your avi is supported by FFMPEG. use this tool To check what exactly the format is and look up the FFMPEG library help/support to see if the format is supported or not.