My code:
HINSTANCE hdll = LoadLibrary(L"D:\\MyDLL\\Debug\\Mydll.dll");
if (!hDLL) {
std::cout << "could not load dll" << std::endl;
return EXIT_FAILURE;
}
EntryPointfuncPtr test;
test = (EntryPointfuncPtr)GetProcAddress(hDLL,"create");
test();
My test() crashes here as the create() is name mangled..I use the name mangled name eg ?create## it works fine...
PLZ tell where have I gon wrong..
I have exported a class in a dll
Related
My concern is about run-time polymorphism. I quite understand the notion of using base-class pointers and the "virtual" keyword in order to achieve it. And I do understand why the compiler defers call resolution to run-time. But, I am confused thinking why the compiler would defer it when references are used, instead of pointers. A reference, once assigned, cannot refer to anything else. So, doesn't the compiler already know what object the reference refers to? So, why doesn't it statically resolve function calls when there is a base-class reference, not pointer? This is different for a pointer because it can point to any object at run-time within the class hierarchy. But the reference is fixed!
Here is a code snippet:
class Base
{
protected:
int m_value;
public:
Base(int value)
: m_value(value)
{
}
virtual const char* getName() const { return "Base"; }
int getValue() const { return m_value; }
};
class Derived: public Base
{
public:
Derived(int value)
: Base(value)
{
}
virtual const char* getName() const { return "Derived"; }
};
int main()
{
Derived derived(5);
std::cout << "derived is a " << derived.getName() << " and has value " <<
derived.getValue() << '\n';
Base &ref = derived;
std::cout << "ref is a " << ref.getName() << " and has value " << ref.getValue() << '\n';
Base *ptr = &derived;
std::cout << "ptr is a " << ptr->getName() << " and has value " << ptr- >getValue() << '\n';
return 0;
}
"The reference is fixed" premise is false. A reference may refer to the base subobject of any object in the hierarchy, just like the pointer can. The compiler cannot tell from the reference what the most-derived object is, no more than it can from the pointer.
Consider:
void DoSomething(const Base& b) { std::cout << b.getName(); }
Base base;
DoSomething(base); // b is bound to Base object. Prints "Base"
Derived derived;
DoSomething(derived); // b is bound to Base subobject of Derived object.
// Prints "Derived"
I am trying to write a function, that saves a QImage object on a hard drive as image-type file. Here's the code of the function:
void ImageMaster::saveImage()
{
QStringList mimeTypeFilters;
foreach (const QByteArray &mimeTypeName, QImageWriter::supportedMimeTypes()) {
mimeTypeFilters.append(mimeTypeName);
}
mimeTypeFilters.sort();
const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
QFileDialog dialog(this, tr("Save Image"),
picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last());
dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setMimeTypeFilters(mimeTypeFilters);
dialog.selectMimeTypeFilter("image/png");
if (dialog.exec() == QDialog::Accepted) {
qDebug() << "accepted!";
const QString& fileName = dialog.selectedFiles().first();
qDebug() << fileName;
QImageWriter writer;
writer.setFormat("png");
writer.setDevice(new QFile(fileName));
writer.setFileName(fileName);
if (!writer.write(getCurrentImage())) {
qDebug() << writer.errorString();
}
}
else {
qDebug() << "not accepted!";
}
}
And here's the output when I try to save image previously loaded into my program from the hard drive:
accepted!
"C:/Users/toshiba/Pictures/im.png"
QFSFileEngine::open: No file name specified
QFile::remove: Empty or null file name
"Device not writable"
What do I do wrong? The getCurrentImage method returns a perfectly looking when displayed QImage object.
I'm trying to refactor a rather complicated piece of code and run into segfaults during loading the library. This is a minimal example of what I could single out to be the source of the segfault:
#include <iostream>
#include <string>
#include <map>
class Manager {
public:
class Action{
};
static bool registerAction(const Action* a, const char* name);
};
namespace Actions {
class ExampleAction : public Manager::Action {
};
namespace {
static bool available = Manager::registerAction(new ExampleAction(),"ExampleAction");
}
}
namespace {
typedef std::map<const std::string,const Manager::Action*> ActionList;
static ActionList sActions;
}
bool Manager::registerAction(const Action* a, const char* name){
std::cout << "attempting to register action " << a << " as " << name << std::endl;
sActions[name] = a;
std::cout << "done" << std::endl;
return true;
}
int main(){
std::cout << "hello!" << std::endl;
for(auto it:sActions){
std::cout << it.first << std::endl;
}
std::cout << "world!" << std::endl;
return 0;
}
It compiles fine with g++ 4.8.4 using the --std=c++11 flag, but upon execution, this happens:
attempting to register action 0x1ebe010 as ExampleAction
Segmentation fault (core dumped)
The line attempting to register comes first, which is of course expected, but the line assigning the value to the static map instance causes the crash, and I don't understand the reason. I'm probably being stupid here, but still - any suggestions on how to fix this?
Here is my code:
class Test
{
public:
Test(){ cout << "constructor" << endl; }
~Test(){ cout << "destructor" << endl; }
void show(){ cout << "show" << endl; }
};
int main()
{
vector<shared_ptr<Test>> vec;
vec.push_back(make_shared<Test>(Test()));
vec[0]->show();
vec.clear();
return 0;
}
I run the code above in Visual Studio and here is the result:
constructor
destructor
show
destructor
In my opinion, constructor and destructor before show come from Test(). We created a temporary object as the parameter of make_shared<>(). So here we call the constructor and destructor.
But I don't know why there isn't any constructor after show. Won't make_shared new an object? How could we have a destructor without any constructor after show? Or it's because the compiler did something that I don't know?
Gotta be aware of compiler-generated copy constructors here (or elided copies depending on compiler implementation):
class Test
{
public:
Test(){ cout << "constructor" << endl; }
~Test(){ cout << "destructor" << endl; }
Test(const Test& other){cout << "copy" << std::endl;}
void show(){ cout << "show" << endl; }
};
int main()
{
vector<shared_ptr<Test>> vec;
vec.push_back(make_shared<Test>(Test()));
vec[0]->show();
vec.clear();
return 0;
}
constructor
copy
destructor
show
destructor
Demo
The generation of a copy constructor when there is a user defined destructor is deprecated, so in our case the compiler is either eliding the copy, or actually generating a copy constructor.
Edit
A word to the wise. The Rule of Three has become the Rule of Five (and a half) in C++11 and beyond. I personally like the Rule of all or nothing which essentially states that if you define any one of the special member functions (ctors, dtor, assignment), then you should define ALL of them (explicitly default or delete them, that is)
On Windows, one can get any special folder path using SHGetKnownFolderPath or SHGetSpecialFolder (If I remember correctly this last one). However, I want the reverse, I have a path and want to know which special folder it belongs to, if any. I prefer this approach, because to find out if a given path's is in a particular special folder or not, I'll have to enumerate all special folders for all users which is a bit of ugly, but if there's no other way, the sky is the limit :)
I searched it but couldn't find anything useful. So does WinApi has a function to do just that?
Thanks.
You can use IKnownFolderManager::FindFolderFromPath
Available since Vista.
PS: check out the CComPtr<> class for simpler interfacing with COM.
Here is a sample i just made up, showing how to use it:
#include <atlsafe.h>
#include <Shobjidl.h>
#include <comdef.h>
void PrintKnownFolder( const CComPtr<IKnownFolder>& folder )
{
KNOWNFOLDER_DEFINITION def;
HRESULT hr = folder->GetFolderDefinition( &def );
if( SUCCEEDED(hr) ) {
std::wcout << L"Result: " << def.pszName << std::endl;
FreeKnownFolderDefinitionFields( &def );
} else {
_com_error err(hr);
std::wcout << L"Error while querying GetFolderDefinition: " << err.ErrorMessage() << std::endl;
}
}
class CCoInitialize
{
public:
CCoInitialize() : m_hr(CoInitialize(NULL)) { }
~CCoInitialize() { if (SUCCEEDED(m_hr)) CoUninitialize(); }
operator HRESULT() const { return m_hr; }
private:
HRESULT m_hr;
};
bool test()
{
CCoInitialize co;
CComPtr<IKnownFolderManager> knownFolderManager;
HRESULT hr = knownFolderManager.CoCreateInstance( CLSID_KnownFolderManager );
if( !SUCCEEDED(hr) ) {
_com_error err(hr);
std::wcout << L"Error while creating KnownFolderManager: " << err.ErrorMessage() << std::endl;
return false;
}
CComPtr<IKnownFolder> folder;
hr = knownFolderManager->FindFolderFromPath( L"C:\\Users\\All Users\\Microsoft", FFFP_NEARESTPARENTMATCH, &folder );
if( SUCCEEDED(hr) ) {
PrintKnownFolder(folder);
} else {
_com_error err(hr);
std::wcout << L"Error while querying KnownFolderManager for nearest match: " << err.ErrorMessage() << std::endl;
}
// dispose it.
folder.Attach( NULL );
hr = knownFolderManager->FindFolderFromPath( L"C:\\Users\\All Users\\Microsoft", FFFP_EXACTMATCH, &folder );
if( SUCCEEDED(hr) ) {
PrintKnownFolder(folder);
} else {
_com_error err(hr);
std::wcout << L"Error while querying KnownFolderManager for exact match: " << err.ErrorMessage() << std::endl;
}
return true;
}
CCoInitialize borrowed from The Old New Thing