I'm trying to write game using Ogre engine. I had a lot of problems - GCC didn't compiled program because it didn't found OgreMain_d and OIS_d... I created symbolic links (I'm using Linux) to libOgreMain.so.1.7.2 and libOIS-1.3.0.so and GCC compiled my program, but... the program shows error:
OGRE EXCEPTION(6:FileNotFoundException): 'resources.cfg' file not found! in ConfigFile::load at /home/m4tx/Programs/ogre_src_v1-7-2/OgreMain/src/OgreConfigFile.cpp (line 83)
My code:
#define OGRE_CHANGE1 ((1 << 16) | (1 << 8))
#include "Ogre.h"
#include "ExampleApplication.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#else
#include <iostream>
#endif
// Dziedziczymy ExampleApplication
class MyApp : public ExampleApplication
{
protected:
public:
MyApp()
{
}
~MyApp()
{
}
protected:
void createScene(void)
{
}
};
#ifdef __cplusplus
extern "C" {
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
MyApp App;
try
{
App.go();
return 0;
}
catch (Ogre::Exception& e)
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.getFullDescription().c_str(), "Exception!",
MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr <<"Exception:\n";
std::cerr <<e.getFullDescription().c_str() <<"\n";
#endif
return 1;
}
}
#ifdef __cplusplus
}
#endif
Please help.
Your hint is clearly in the error message. The example framework for Ogre expects certain files to be available, such as resource.cfg and even plugins.cfg. Make sure this is in the path, and that the media required by those resources is also available.
Related
I wrote a c-code designed for linux platform.
Now, I want to make it cross-platform so to use in Windows as-well.
In my code, I dlopen an so file and utilize the functions inside it.
Below is how my code looks like. But I just found out that in windows, the way to load and use dynamic library is quite different.
void *mydynlib
mydynlib= dlopen("/libpath/dynlib.so",RTLD_LAZY);
void (*dynfunc1)() = dlsym(mydynlib,"dynfunc1");
void (*dynfunc2)(char*, char*, double) = dlsym(mydynlib,"dynfunc2");
int (*dynfunc3)() = dlsym(mydynlib,"dynfunc3");
From what I found, I need to use LoadLibrary & GetProcAddress instead of dlopen & dlsym. However, I do not know how to convert above line for windows using those. I've tried to search some examples for hours but couldn't find exact solution. If someone had this kind of experience, please give me a tip.
Excuse me if this is too obvious problem. I'm quite new to C. I usually write my program in python.
Once in my youth I created something like this:
/* dlfcn.h */
#ifndef DLFCN_H
#define DLFCN_H
#define RTLD_GLOBAL 0x100 /* do not hide entries in this module */
#define RTLD_LOCAL 0x000 /* hide entries in this module */
#define RTLD_LAZY 0x000 /* accept unresolved externs */
#define RTLD_NOW 0x001 /* abort if module has unresolved externs */
/*
How to call in Windows:
void *h = dlopen ("path\\library.dll", flags)
void (*fun)() = dlsym (h, "entry")
*/
#ifdef __cplusplus
extern "C" {
#endif
void *dlopen (const char *filename, int flag);
int dlclose (void *handle);
void *dlsym (void *handle, const char *name);
const char *dlerror (void);
#ifdef __cplusplus
}
#endif
#endif
and dlfcn.c:
/* dlfcn.c */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
static struct {
long lasterror;
const char *err_rutin;
} var = {
0,
NULL
};
void *dlopen (const char *filename, int flags)
{
HINSTANCE hInst;
hInst= LoadLibrary (filename);
if (hInst==NULL) {
var.lasterror = GetLastError ();
var.err_rutin = "dlopen";
}
return hInst;
}
int dlclose (void *handle)
{
BOOL ok;
int rc= 0;
ok= FreeLibrary ((HINSTANCE)handle);
if (! ok) {
var.lasterror = GetLastError ();
var.err_rutin = "dlclose";
rc= -1;
}
return rc;
}
void *dlsym (void *handle, const char *name)
{
FARPROC fp;
fp= GetProcAddress ((HINSTANCE)handle, name);
if (!fp) {
var.lasterror = GetLastError ();
var.err_rutin = "dlsym";
}
return (void *)(intptr_t)fp;
}
const char *dlerror (void)
{
static char errstr [88];
if (var.lasterror) {
sprintf (errstr, "%s error #%ld", var.err_rutin, var.lasterror);
return errstr;
} else {
return NULL;
}
}
You could use a set of macros that change depending on the OS you're on:
#ifdef __linux__
#define LIBTYPE void*
#define OPENLIB(libname) dlopen((libname), RTLD_LAZY)
#define LIBFUNC(lib, fn) dlsym((lib), (fn))
#elif defined(WINVER)
#define LIBTYPE HINSTANCE
#define OPENLIB(libname) LoadLibraryW(L ## libname)
#define LIBFUNC(lib, fn) GetProcAddress((lib), (fn))
#endif
I'm trying to build a windows dll using mingw-64 that once loaded starts printing "Hello World" indefinetly.
Here's my dll.c
#include <stdio.h>
#include <windows.h>
#include "dll.h"
#include "main.h"
HINSTANCE hThisModule;
DWORD mainThread() {
while(1) {
printf("Hello world!");
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
static HANDLE hThread;
hThisModule = hinstDLL;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hThread = CreateThread(0, 0, mainThread, 0, 0, 0);
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
void dummy() {
Hello();
}
and here's my dll.h:
#ifndef DLL_H_
#define DLL_H_
#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
#else
/* EXE import */
#define EXPORT __declspec(dllimport)
#endif
#endif /* DLL_H_ */
so I've built a simple program that loads my DLL to see if it's working correctly, here it is: hello.cpp
#include <windows.h>
#include <iostream>
typedef int (__stdcall *f_funci)();
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("./wow.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Now, when I compile hello.cpp into hello.exe and dll.c into wow.dll, I get nothing on my console. What's wrong?
As has been already mentioned, your mainThread function has wrong signature. Try something like this:
DWORD WINAPI mainThread(LPVOID lpParam)
{
UNREFERENCED_PARAMETER(lpParam);
while (1)
{
printf("Hello world!\n");
Sleep(1000);
}
return 0;
}
This works just fine for me. I modified your .exe so that you could drag and drop .dll onto it to test:
#include <windows.h>
#include <iostream>
int main(int argc, char *argv[])
{
if (argc < 2)
{
std::cout << "drag drop dll over exe" << std::endl;
std::cin.get();
return EXIT_FAILURE;
}
HINSTANCE hGetProcIDDLL = LoadLibraryA(argv[1]);
if (!hGetProcIDDLL)
{
std::cout << "could not load the dynamic library" << std::endl;
std::cin.get();
return EXIT_FAILURE;
}
std::cin.get();
return EXIT_SUCCESS;
}
First, I'd like to mention that it is not advisable to implement such a busy loop in your thread.
As for the issue you are experiencing, there are several potential issues here:
printf is a CRT function, however you are calling CreateThread() instead of beginthread(ex), so the CRT is not initialized properly.
Dll entry point is a notoriously problematic place. You can hardly call any kernel32 function from there, let alone CRT ones (see DllMain entry point and Dynamic Link Library Best Practices).
In most cases, it is advisable to implement separate Init and Exit functions that the client will need to call when using your library.
I'm trying to write a C++ program that will communicate with different DB providers. Everything works fine now, however upon exiting I'm trying to close the connection and the disconnect command crashes. At the moment I'm testing with SQLite, so it probably belong to this specific one.
Do I have to close the connection to the SQLite upon program termination? I believe generally it is a good idea to release the resources the program is using, but what about this case? I mean in this case the SQLite DB file will be released back to the system when the program exits, so its not actually a loss.
Thank you.
[EDIT]
As requested I'm submitting the code that I use.
In DLL1 (database.h):
#ifndef DBMANAGER_DATABASE
#define DBMANAGER_DATABASE
class __declspec(dllexport) Database
{
public:
Database();
virtual ~Database();
static void *operator new(size_t size);
static void operator delete(void *ptr, size_t size);
};
#endif
In DLL1 (database.cpp)
#include <string>
#include "database.h"
Database::Database()
{
}
Database::~Database()
{
}
void *Database::operator new(std::size_t size)
{
return ::operator new( size );
}
void Database::operator delete(void *ptr, std::size_t size)
{
return ::operator delete( ptr );
}
In DLL2: (database_sqlite.h):
#ifndef DBMANAGER_SQLITE
#define DBMANAGER_SQLITE
class __declspec(dllexport) SQLiteDatabase : public Database
{
public:
SQLiteDatabase();
virtual ~SQLiteDatabase();
virtual int Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg);
protected:
void GetErrorMessage(int code, std::wstring &errorMsg);
private:
sqlite3 *m_db;
};
#endif
In DLL2: (database_sqlite.cpp)
#ifdef WIN32
#include <windows.h>
#pragma execution_character_set("utf-8")
#endif
#include <vector>
#include <string>
#include <sqlext.h>
#include "sqlite3.h"
#include "database.h"
#include "database_sqlite.h"
SQLiteDatabase::SQLiteDatabase() : Database()
{
}
SQLiteDatabase::~SQLiteDatabase()
{
sqlite3_close( m_db );
}
int SQLiteDatabase::Connect(const char *selectedDSN, std::vector<std::wstring> &errorMsg)
{
int result = 0;
std::wstring errorMessage;
int res = sqlite3_open( selectedDSN, &m_db );
if( res != SQLITE_OK )
{
// get error messages GetErrorMessage( res, errorMessage );
errorMsg.push_back( errorMessage );
result = 1;
}
else
{
res = sqlite3_exec( m_db, "PRAGMA foreign_keys = ON", NULL, NULL, NULL );
if( res != SQLITE_OK )
{
// get error message GetErrorMessage( res, errorMessage );
errorMsg.push_back( errorMessage );
result = 1;
}
}
return result;
}
In DLL3: (dialogs.cpp)
#ifdef __GNUC__
#pragma implementation "dialogs.h"
#endif
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include <vector>
#include "sqlite3ext.h"
#include "database.h"
#include "database_sqlite.h"
#ifdef _WINDOWS
BOOL APIENTRY DllMain( HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
lpReserved = lpReserved;
hModule = hModule;
int argc = 0;
char **argv = NULL;
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
extern "C" __declspec(dllexport) Database *DatabaseProfile(Database *db)
{
db = new SQLiteDatabase;
return db;
}
In main application (test_app.cpp):
#include "stdafx.h"
#include "database.h"
#include <windows.h>
#include <stdio.h>
typedef Database *(__cdecl *MYFUNC)(Database *);
class A
{
public:
A(Database *db)
{
m_db = NULL;
HINSTANCE hInst = LoadLibrary( TEXT( "dialogs.dll" ) );
MYFUNC func = (MYFUNC) GetProcAddress( hInst, "DatabaseProfile" );
m_db = func( db );
}
~A()
{
}
Database *GetDatabase()
{
return m_db;
}
private:
Database *m_db;
};
int _tmain(int argc, _TCHAR* argv[])
{
Database *db = NULL, *m_db;
A *a = new A( db );
m_db = a->GetDatabase();
delete m_db;
delete a;
return 0;
}
[EDIT]
Running this code I am getting the crash executing "delete "m_db" line. SQLite is compiled in from source code.
Any idea?
Thank you.
I'm building a password filter as demonstrated with by the following link: http://msdn.microsoft.com/en-us/library/windows/desktop/ms721882(v=vs.85).aspx
I attempted to build a dll and load it on a test machine following the instructions provided by MS and discovered something was obviously wrong as the dll was not getting loaded. So I then decided to run a unit test program on the dll and that doesn't seem to work either. Rather, it works if I use mangled functions without use of the extern "C" directive or an .def file. As soon as I do use extern "C" or the def file, the code doesn't work.
The Code below produces the error code 127: The specified procedure could not be found. Despite me using extern "C" and using Dependency Walker to get the name of the function, I'm told by the code that the function could not be found.
Here is the unit test app:
#include "stdafx.h"
#include <Windows.h>
#include <NTSecAPI.h>
#include <strsafe.h>
typedef NTSTATUS (__stdcall *MYPROC)(PUNICODE_STRING, ULONG, PUNICODE_STRING);
int _tmain(int argc, _TCHAR* argv[])
{
MYPROC ProcAdd;
HMODULE MyDllHnd = LoadLibrary(TEXT("C:\\Users\\mmatovic\\Documents\\Visual Studio 2012\\Projects\\PasswordFilterUnitTest\\Debug\\PasswordFilter.dll"));
if (NULL == MyDllHnd)
{
DWORD dwError = GetLastError();
cout << "Error: " << dwError << endl;
}
ProcAdd = (MYPROC)GetProcAddress(
MyDllHnd,
"PasswordChangeNotify");
ULONG rid = 0;
if (NULL != ProcAdd)
{
(ProcAdd)((PUNICODE_STRING)"test",(ULONG)0,(PUNICODE_STRING)"test");
} else {
DWORD dwProcError = GetLastError();
cout << "Error: " << dwProcError << endl;
}
return 0;
}
Here is the code for the actual DLL:
#include "stdafx.h"
#define LOGFILE "c:\\PasswordFilter.txt"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void WriteToLog (PUNICODE_STRING str)
{
#ifdef LOGFILE
FILE* log = fopen(LOGFILE, "a");
if(NULL == log)
{
return;
}
fprintf(log, "%s\r\n", str);
fclose(log);
#endif
return;
}
BOOLEAN __stdcall InitializeChangeNotify(void)
{
return TRUE;
}
NTSTATUS __stdcall PasswordChangeNotify(
PUNICODE_STRING UserName,
ULONG RelativeId,
PUNICODE_STRING NewPassword
)
{
WriteToLog(UserName);
WriteToLog(NewPassword);
return 0;
}
BOOLEAN __stdcall PasswordFilter(
PUNICODE_STRING AccountName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOLEAN SetOperation
)
{
return TRUE;
}
And lastly the contents of the .def file
LIBRARY PasswordFilter
EXPORTS
InitializeChangeNotify
PasswordChangeNotify
PasswordFilter
Also the stdafx.h file generated in VS for the DLL code:
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <stdio.h>
#include <windows.h>
#include <winnt.h>
#include <NTSecAPI.h>
I'm trying to create a cross-platform program. I just created a class and made a function which gets the path of the current user. I wanted to use that path later. But somehow I get these errors :
"/usr/include/x86_64-linux-gnu/sys/stat.h:-1: In member function 'void FileManager::p_getfilepath()':"
"/usr/include/x86_64-linux-gnu/sys/stat.h:105: error: expected unqualified-id before string constant"
"/home/david/VocabularyTrainer/filemanager.cpp:31: error: expected '}' at end of input"
btw the 31th line is the last line here in this code :
void FileManager::p_getfilepath()
{
#ifdef Q_OS_WIN32
#include <windows.h>
#endif
#ifdef Q_OS_LINUX
#include <sys/stat.h>
struct passwd *p;
uid_t uid;
if ((p = getpwuid(uid = geteuid())) == NULL)
{
QMessageBox* mb;
mb->setText("");
mb->exec();
delete mb;
}
else
{
filepath = p->pw_dir;
}
#endif
}
Anyone knows what's wrong? I'm on linux mint.
By including your headers inside your class functions, you're making everything in the header a part of the function.
#ifdef Q_OS_WIN32
#include <windows.h>
#endif
#ifdef Q_OS_LINUX
#include <sys/stat.h>
#endif
void FileManager::p_getfilepath()
{
#ifdef Q_OS_LINUX
struct passwd *p;
uid_t uid;
if ((p = getpwuid(uid = geteuid())) == NULL)
{
QMessageBox* mb;
mb->setText("");
mb->exec();
delete mb;
}
else
{
filepath = p->pw_dir;
}
#endif
}