I have been having issues using an anonymous mutex (boost::interprocess::interprocess_mutex) in a boost::interprocess::managed_shared_memory instance. Namely, issues arise if the software crashes; the mutex may remain locked (depending on its state at time of crash). It can make debugging interesting too :).
My understanding is that I can substitute the interprocess_mutex with boost::interprocess::file_lock (FL). #DaveF posted some questions that I would like to build upon. I'd like to have a good understanding what I'm getting myself into before I put FL into use.
Can I use an anonymous boost::interprocess::condition_variable (CV) with FL? Having looked through the code, it appears that it will work.
In using a CV, am I opening myself up to the same problems I have experienced when using mutex (ie. if the application unexpectedly ends without proper cleanup/finalisation)?
What is the best way to create a FL. I've thought about something similar to the following...
Note code may not compile:
namespace bi = boost::interprocess;
namespace bf = boost::filesystem;
const std::string strSharedMemName = std::string("cp_shdmem_") + std::to_string(nIdx);
const std::string strNamedMutexName = strSharedMemName + "_mtx";
// I'm working on Linux, but would like to Boost to create a temporary file path.
const bf::path pathTmpFile =
bf::temp_directory_path() / (strNamedMutexName + ".txt");
{
// 1. So can I just create the file? What happens if it exists? Boost docs say this
// about the file_lock constructor:
// "Throws interprocess_exception if the file does not exist
// or there are no operating system resources."
// 2. What happens if file already exists?
bf::ofstream f(pathTmpFile);
}
// Create.
bi::file_lock lockFile(pathTmpFile.string().c_str());
// Lock.
bi::scoped_lock<bi::file_lock> lockNamed(lockFile);
Platform specifics:
Ubuntu 17.10
Boost 1.63
GCC 7.2
I'm building a Windows 8.1 DirectX app and trying to load in an external to store level data.
The relevant code currently is (this method is called in the AssetHandler constructor):
void AssetHandler::LoadLevelsData()
{
unsigned int i = 0;
std::string lineData;
this->currentFile.open("Assets/reg.txt");
//Below statement here purely to check if the blasted thing is opening
if (this->currentFile.is_open())
{
i++;
}
while (std::getline(this->currentFile, lineData))
{
levels[i] = lineData;
i++;
}
currentFile.close();
}
The problem that i'm having is that the file does not appear to be opening. I have tried:
Using a full path
Opening the file in the initialisation list
A breakpoint shows that it is jumping over the if and while
I found some information saying that DirectX has constraints on working with external files but it did not specify exactly what these were.
The Item Type was set to 'Does not participate in build'. Setting this value to 'Text' solved the problem.
I want to use time related method and function in Win32 VC++ application. VC++ provides CTime class. I want to know that using CTime class in non mfc project is safe. Is there any alternatives for CTime class for using in non mfc win32 application.
Thank you.
You can try using GetSystemTime;
Retrieves the current system date and time. The system time is
expressed in Coordinated Universal Time (UTC).
To retrieve the current system date and time in local time, use the
GetLocalTime function.
A sample code piece.
#include <windows.h>
#include <iostream>
void main(){
SYSTEMTIME st;
GetSystemTime(&st);
char currentTime[84] = "";
sprintf_s(currentTime,"%d/%d/%d %d:%d:%d %d",
st.wDay,st.wMonth,st.wYear, st.wHour,
st.wMinute, st.wSecond , st.wMilliseconds);
std::cout<<"time: "<<currentTime;
getchar();
}
Using MFC in a console (non GUI) application is safe. Even the Project Wizard to generate a Win32 Console Application has a checkbox to specify whether to include the MFC libraries or not.
This compiles/works fine with Xcode 5, but causes a compile error with Xcode 6 Beta 4:
objc_msgSend(anItem.callback_object,
NSSelectorFromString(anItem.selector), dict);
This is a 3rd-party component, so while I have the source code, it's not really my code and I'm hesitant to change it much (despite my personal opinion of 'wtf why are they using objc_msgSend??').
Image with possibly useful detail (error in error browser):
If you think having to do this is annoying and pointless you can disable the check in the build settings by setting 'Enable strict checking of objc_msgSend Calls' to no
Just to spare watching a WWDC video, the answer is you need to strong type objc_msgSend for the compiler to build it:
typedef void (*send_type)(void*, SEL, void*);
send_type func = (send_type)objc_msgSend;
func(anItem.callback_object, NSSelectorFromString(anItem.selector), dict);
Here is another sample when calling instance methods directly, like this:
IMP methodInstance = [SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);
Use strong type for methodInstance to make LLVM compiler happy:
typedef void (*send_type)(void*, SEL, void*);
send_type methodInstance = (send_type)[SomeClass instanceMethodForSelector:someSelector];
methodInstance(self, someSelector, someArgument);
Do not forget to set send_type's return and argument types according to your specific needs.
I found the answer, and it's in Session 417 from 2014 WWDC "What's New in LLVM". If you find this code in a 3rd party library, such as Apsalar, updating to the latest version fixes it (probably because it's not distributed as a lib, ha). For an example of casting of these calls, see THObserversAndBinders library - I'm using it and noticed that the author updated the code, such as here:
https://github.com/th-in-gs/THObserversAndBinders/blob/master/THObserversAndBinders/THObserver.m
This could also be caused by running pod install using Cocoapods 0.36.beta.2. I have reported the issue to CocoaPods. "Workaround" by using CocoaPods 0.35
Setting Enable strict checking of objc_msgSend Calls to NO, solved my issue. Below is the screenshot
Maciej Swic is right.This is caused in Pods after updating Cocoapods to 0.36.beta.2.
I found a simple workaround by type casting objc_msgSend:
id (*typed_msgSend)(id, SEL) = (void *)objc_msgSend;
id<MyProtocol> obJ = typed_msgSend(controller, #selector(myselector));
I was getting this error with QuickDialog. Following on to james_alvarez's answer but for AppCode, go to Project Settings, then click on QuickDialog under Project/Shared Settings, scroll down to ENABLE_STRICT_OBJC_MSGSEND and enter NO for Debug and Release.
You can also disable this with a post install hook:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_STRICT_OBJC_MSGSEND'] = 'NO'
end
end
end
#include <objc/message.h>
void foo(void *object) {
typedef void (*send_type)(void *, SEL, int);
send_type func = (send_type)objc_msgSend;
func(object, sel_getUid("foo:"), 5);
}
Following the accepted answer- to find the answer in the given codebase might be cumbersome for few, so here's the quick snap that should solve this problem.
I edited the code in ActionSheetPicker in my project, which was causing me the same problem, like this -
- (void)notifyTarget:(id)target didSucceedWithAction:(SEL)action origin:(id)origin {
if ([target respondsToSelector:action]) {
((id (*)(id, SEL, NSDate *, id))objc_msgSend)(target, action, self.selectedDate, origin);
return;
} else if (nil != self.onActionSheetDone) {
self.onActionSheetDone(self, self.selectedDate, origin);
return;
}
NSAssert(NO, #"Invalid target/action ( %s / %s ) combination used for ActionSheetPicker", object_getClassName(target), (char *)action);
}
So look at the change that objc_msgSend portion has, compared to your current code.
The idea is to include the type of the parameters you are passing to objc_msgSend
((void(*)(id,SEL,id))objc_msgSend)(target, sel, newValue);
Change the code like above, after Xcode 12, simply setting Setting Enable strict checking of objc_msgSend Calls to NO does not help. modify the (id,SEL,id) for your need, for example(id,SEL) for two arguments, etc
This block of code reproduces the error:
- (void)reportSuccess:(void(^)(void))success
{
success(what_is_this);
}
Guess where error is? Of course, what_is_this is not declared, but somehow magically it shows another error. In other words looks like if you have block, you can put any parameters when calling it, even non existent variables.
I'm trying to implement http://msdn.microsoft.com/en-us/library/dd377634%28v=VS.85%29.aspx on Qt, to generate a poster frame/thumbnail for video files.
I have installed both Windows Vista and Windows 7 SDK. I put:
#include "qedit.h"
in my code (noting there is also one in C:\Qt\2010.04\mingw\include), I add:
win32:INCLUDEPATH += $$quote(C:/WindowsSDK/v6.0/Include)
to my *.pro file. I compile and get " error: sal.h: No such file or directory". Finding this in VC++ I add
win32:INCLUDEPATH += $$quote(C:/Program Files/Microsoft Visual Studio 10.0/VC/include)
And now have 1400 compile errors. So, I abandon that and just add:
win32:LIBS += C:/WindowsSDK/v7.1/Lib/strmiids.lib
to my *.pro file and try to run (without including any headers):
IMediaDet mediadet;
But then I get "error: IMediaDet: No such file or directory".
#include "qedit.h"
gives me the same error (it looks like it's pointing to the Qt version) and
#include "C:/WindowsSDK/v6.0/Include/qedit.h"
goes back to generating 1000's of compile errors.
Sigh, so much trouble for what should be 10 lines of code...
Thanks for your comments and help
Since you say you are "a C++/Qt newbie" then I suspect that the real issue may be that you are attempting to load the library yourself rather than simply linking your application to it?
To link an external library into your application with Qt all you need to do is modify the appropriate .pro file. For example if the library is called libfoo.dll you just add
LIBS += -L/path/to/lib -lfoo
You can find more information about this in the relevant section of the qmake manual. Note that qmake commonly employs Unix-like notation and transparently does the right thing on Windows.
Having done this you can include the library's headers and use whatever classes and functions it provides. Note that you can also modify the project file to append an include path to help pick up the headers eg.
INCLUDEPATH += /path/to/headers
Again, more information in the relevant section of the qmake manual.
Note that both these project variables work with relative paths and will happily work with .. to mean "go up a directory" on all platforms.
Note that qedit.h requires dxtrans.h, which is part of DirectX9 SDK.
You can find dxtrans.h in DirectX SDK from August 2006. Note that dxtrans.h is removed from newer DirectX SDKs.
Do you have access to the source of the external library? The following assumes that you do.
What I do when I need to extract a class from a library with only functions resolved, is to use a factory function in the library.
// Library.h
class SomeClass {
public:
SomeClass(std::string name);
// ... class declaration goes here
};
In the cpp file, I use a proxy function outside the extern "C" when my constructor requires C++ parameters (e.g. types such as std::string), which I pass as a pointer to prevent the compiler from messing up the signature between C and C++. You can avoid the extra step if your constructor doesn't require parameters, and call new SomeClass() directly from the exported function.
// Library.cpp
#include "Library.h"
SomeClass::SomeClass(std::string name)
{
// implementation details
}
// Proxy function to handle C++ types
SomeClass *ImplCreateClass(std::string* name) { return new SomeClass(*name); }
extern "C"
{
// Notice the pass-by-pointer for C++ types
SomeClass *CreateClass(std::string* name) { return ImplCreateClass(name); }
}
Then, in the application that uses the library :
// Application.cpp
#include "Library.h"
typedef SomeClass* (*FactoryFunction)(std::string*);
// ...
QLibrary library(QString("MyLibrary"));
FactoryFunction factory = reinterpret_cast(library.resolve("CreateClass"));
std::string name("foobar");
SomeClass *myInstance = factory(&name);
You now hold an instance of the class declared in the library.