Компоновщик не знает OpenFileNameA
В главной функции пишу:
Код:
...
ZeroMemory(&ofn , sizeof( ofn));
ofn.lStructSize = sizeof ( ofn );
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '�';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All�*.*�Text�*.TXT�";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL ;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
GetOpenFileName(&ofn);
MessageBox ( NULL , ofn.lpstrFile , "File Name" , MB_OK);
...
ZeroMemory(&ofn , sizeof( ofn));
ofn.lStructSize = sizeof ( ofn );
ofn.hwndOwner = NULL;
ofn.lpstrFile = szFile;
ofn.lpstrFile[0] = '�';
ofn.nMaxFile = sizeof(szFile);
ofn.lpstrFilter = "All�*.*�Text�*.TXT�";
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL ;
ofn.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST;
GetOpenFileName(&ofn);
MessageBox ( NULL , ofn.lpstrFile , "File Name" , MB_OK);
...
Код:
openfile.o:openfile.c|| undefined reference to `GetOpenFileNameA@4'
Спасибо за Ваше внимание.
MinGW\lib\libcomdlg32.a
Приведу пример на базе вашей задачи. Может пригодится. Класс здесь в минимальной реализации, можно его развить.
Код:
#include <iostream>
#include <windows.h>
using namespace std;
class DllHandler {
HINSTANCE hDLL; // Handle для DLL (NULL - не загружена)
//прячим в privat конструктор копий и =
DllHandler(const DllHandler &);
DllHandler & operator=(const DllHandler &);
public:
DllHandler(const char dll_name[]) { // конструктор принимает имя dll
hDLL = LoadLibraryA(dll_name);
}
~DllHandler() {
freeDll();
}
BOOL isLoaded() { // проверка загруженности dll
if (hDLL) return true;
else return false;
}
void *getFun(const char fun_name[]) { // получить ф-цию из dll по ее имени
void *vp = NULL;
if (hDLL) vp = (void *)GetProcAddress(hDLL, fun_name);
return vp;
}
void freeDll() { // выгрузка dll
if (hDLL) if (FreeLibrary(hDLL)) hDLL = NULL;
}
};
int main() {
OPENFILENAMEA ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof (ofn);
//......
typedef BOOL WINAPI(*FUN)(LPOPENFILENAMEA);
DllHandler hComdlg32("Comdlg32.dll");
FUN fn = (FUN)hComdlg32.getFun("GetOpenFileNameA");
if(fn)
fn(&ofn);
else
MessageBoxA(0, "Ошибка открытия библиотеки или ф-ция отсутствует", "", 0);
return 0;
}
#include <windows.h>
using namespace std;
class DllHandler {
HINSTANCE hDLL; // Handle для DLL (NULL - не загружена)
//прячим в privat конструктор копий и =
DllHandler(const DllHandler &);
DllHandler & operator=(const DllHandler &);
public:
DllHandler(const char dll_name[]) { // конструктор принимает имя dll
hDLL = LoadLibraryA(dll_name);
}
~DllHandler() {
freeDll();
}
BOOL isLoaded() { // проверка загруженности dll
if (hDLL) return true;
else return false;
}
void *getFun(const char fun_name[]) { // получить ф-цию из dll по ее имени
void *vp = NULL;
if (hDLL) vp = (void *)GetProcAddress(hDLL, fun_name);
return vp;
}
void freeDll() { // выгрузка dll
if (hDLL) if (FreeLibrary(hDLL)) hDLL = NULL;
}
};
int main() {
OPENFILENAMEA ofn;
ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof (ofn);
//......
typedef BOOL WINAPI(*FUN)(LPOPENFILENAMEA);
DllHandler hComdlg32("Comdlg32.dll");
FUN fn = (FUN)hComdlg32.getFun("GetOpenFileNameA");
if(fn)
fn(&ofn);
else
MessageBoxA(0, "Ошибка открытия библиотеки или ф-ция отсутствует", "", 0);
return 0;
}
Цитата: sadovoya
Линковщику надо добавить такую библиотеку:
MinGWliblibcomdlg32.a
MinGWliblibcomdlg32.a
Большое спасибо. А что это за библиотека? Commctl32 знаю, а эту нет.
Common Dialog Box Library -- библиотека основных диалогов. Начиная с Vista рекомендуют для Open и Save использовать более современные API (из Common Item Dialog).
Это
Код:
#include <cstdio>
#include <windows.h>
#include <memory> //std::unique_ptr
int main() {
auto lambda_deleater = [](HMODULE* instance) {
FreeLibrary(*instance);
delete instance;
};
auto dll_u_ptr = std::unique_ptr<HMODULE, decltype(lambda_deleater)>
(new HMODULE(LoadLibrary(TEXT("kernel32.dll"))), lambda_deleater);
using FUN = void (CALLBACK* )(LPMEMORYSTATUS);
auto dll_func = (FUN)GetProcAddress(*dll_u_ptr, "GlobalMemoryStatus");
MEMORYSTATUS ms;
dll_func(&ms);
printf("Mem. load is %lu %%\nPress any key...", ms.dwMemoryLoad);
getchar();
return 0;
}
#include <windows.h>
#include <memory> //std::unique_ptr
int main() {
auto lambda_deleater = [](HMODULE* instance) {
FreeLibrary(*instance);
delete instance;
};
auto dll_u_ptr = std::unique_ptr<HMODULE, decltype(lambda_deleater)>
(new HMODULE(LoadLibrary(TEXT("kernel32.dll"))), lambda_deleater);
using FUN = void (CALLBACK* )(LPMEMORYSTATUS);
auto dll_func = (FUN)GetProcAddress(*dll_u_ptr, "GlobalMemoryStatus");
MEMORYSTATUS ms;
dll_func(&ms);
printf("Mem. load is %lu %%\nPress any key...", ms.dwMemoryLoad);
getchar();
return 0;
}
За основу взял материал habrahabr.ru/post/207842/ (пост и комментарии к нему).
здесь), /то можно сделать код лучше, вообще избавившись от new/delete:
В комментариях на habrahabr.ru/post/207842/ подобное тоже обсуждалось.
Еще можно более кратко, но не уверен, что правильно:
Это основано на догадке, что (HINSTANCE__*) -- это и есть HINSTANCE. Код работает, но сомнения есть.
Поскольку HINSTANCE и HMODULE -- это (void *) (см. в MSDN
Код:
...
auto lambda_deleter = [](void* hM) { FreeLibrary( (HMODULE)hM ); };
auto dll_u_ptr = std::unique_ptr<void, decltype(lambda_deleter)>
(LoadLibraryA("kernel32.dll"), lambda_deleter);
...
using FUN = void (CALLBACK* )(LPMEMORYSTATUS);
auto dll_func = (FUN)GetProcAddress((HINSTANCE)dll_u_ptr.get(), "GlobalMemoryStatus");
...
auto lambda_deleter = [](void* hM) { FreeLibrary( (HMODULE)hM ); };
auto dll_u_ptr = std::unique_ptr<void, decltype(lambda_deleter)>
(LoadLibraryA("kernel32.dll"), lambda_deleter);
...
using FUN = void (CALLBACK* )(LPMEMORYSTATUS);
auto dll_func = (FUN)GetProcAddress((HINSTANCE)dll_u_ptr.get(), "GlobalMemoryStatus");
...
Еще можно более кратко, но не уверен, что правильно:
Код:
...
auto dll_u_ptr = std::unique_ptr<HINSTANCE__, decltype(&FreeLibrary)>
(LoadLibraryA("kernel32.dll"), &FreeLibrary);
...
auto dll_func = (FUN)GetProcAddress(dll_u_ptr.get(), "GlobalMemoryStatus");
...
auto dll_u_ptr = std::unique_ptr<HINSTANCE__, decltype(&FreeLibrary)>
(LoadLibraryA("kernel32.dll"), &FreeLibrary);
...
auto dll_func = (FUN)GetProcAddress(dll_u_ptr.get(), "GlobalMemoryStatus");
...