@/*************bridg.dll************///sharedobject.h#ifndef SHAREDOBJECT#define SHAREDOBJECTclass ISharedObject {public: virtual void set(int data) = 0; virtual int get() const = 0; virtual ~ISharedObject() {}};class SharedObject : public ISharedObject {public: SharedObject() : data(-1) {} void set(int data) { this->data = data; } int get() const { return data; }private: int data;};#endif //SHAREDOBJECT//main#include <QSharedMemory>#include "sharedobject.h"#include "SLogger.h"static QSharedMemory* sharedMemory = NULL;const char* slogger::fileName = "bridg.log";extern "C" __declspec(dllexport) bool createSharedMemory(const char* key){ DEBUG() << "Key is: " << key; sharedMemory = new QSharedMemory(key); if ( !sharedMemory->create(sizeof(SharedObject)) ) return false; SharedObject *obj = new SharedObject(); SharedObject *sharedObj = (SharedObject*) sharedMemory->data(); DEBUG() << "Shared instance pointer: " << std::hex << obj; DEBUG() << "Data pointer: " << std::hex << sharedObj; memcpy(sharedObj, obj, sizeof(SharedObject)); return true; //все нормально!}extern "C" __declspec(dllexport) bool destroySharedMemory(){ if ( sharedMemory->detach() ) { delete sharedMemory; return true; } return false;}extern "C" __declspec(dllexport) ISharedObject* getSharedObject(const char* key){ DEBUG() << "Key is: " << key; //key is valid QSharedMemory sm(key); if ( !sm.attach() ) return NULL; //attach is ok ISharedObject *obj = (ISharedObject*)sm.data(); //<--- локальная sharedmemory возвращает невалидный(другой!!, но не NULL) поинтер //ISharedObject *obj = (ISharedObject*)sharedMemory->data(); //<--- с глобальным все ок! DEBUG() << "Shared instance " << std::hex << obj; return obj;}/*************wincons.exe //my test*************/#include <windows.h>#include <iostream>class ISharedObject {public: virtual void set(int data) = 0; virtual int get() const = 0; virtual ~ISharedObject() {}};typedef bool (*FCreate)(const char*);typedef bool (*FDestroy)();typedef ISharedObject* (*FGet)(const char*);static const char* key = "test";int main(){ HINSTANCE dll = LoadLibrary(L"bridg.dll"); if ( dll ) { FCreate _create = (FCreate)GetProcAddress(dll, "createSharedMemory"); FDestroy _destroy = (FDestroy)GetProcAddress(dll, "destroySharedMemory"); FGet _get = (FGet) GetProcAddress(dll, "getSharedObject"); if ( _create ) { bool ret = _create(key); if ( ret ) { ISharedObject* obj = _get(key); if ( obj ) // <---не валиден (!!но не NULL) { //obj->set(42); //std::cout << "Data: " << obj->get() << std::endl; } else std::cout << "Can not get shared instance." << std::endl; } else std::cout << "Can not get create shared memory. Error: " << GetLastError() << std::endl; } else std::cout << "Can not get create function pointer. Error: " << GetLastError() << std::endl; FreeLibrary(dll); } else std::cout << "Can not load library. Error: " << GetLastError() << std::endl; std::getchar(); return 0;}
ISharedObject *obj = (ISharedObject*)sm.data(); //<--- локальная sharedmemory возвращает невалидный(другой!!, но не NULL) поинтер //ISharedObject *obj = (ISharedObject*)sharedMemory->data(); //<--- с глобальным все ок!
C++ (Qt)// пользователь (WinAPI приложение)typedef void * TSHandle;struct CSharedUser {public TSHandle Create( const char * key, size_t size, int access ); void Destroy( void ); void * Acquire( void ); void Release( void ); // data TSHandle mData;}; // хост (Qt приложение) экспортируетTSHandle TS_Create( const char * key, size_t size, int access ) { QSharedMemory * sm = new QSharedMemory(key);// здесь create, attach return sm; } void TS_Destroy( TSHandle h ){ delete (QSharedMemory *) h;} void * TS_Acquire( TSHandle h ){ QSharedMemory * sm = (QSharedMemory *) h; void * data = sm->data(); sm->lock(); return data;} void TS_Release( TSHandle h ){ ((QSharedMemory *) h)->unlock();}
class Manager { typedef void (*FFoo)();public: FFoo foo; bool initialize() { dll_instance = LoadLibrary("some.dll"); if ( !dll_instance ) return false; foo = (FFoo)GetProccessAdress(dll_instance, "foo"); if ( !foo ) return false; return true; } ~Manager() { FreeLibrary(dll_instance); }private: HMODULE dll_instance;};