I'm working on a plugin system for my application. The plugins are in the form of a dll loaded by my application using LoadLibraryEx . I store information about each plugin in an arrray of structs:

typedef struct _InternalPluginInfo
{
    UINT ID;
    HMODULE Module;
    int Flags;
    PluginInfo Info;

} InternalPluginInfo;

But when I try to remove a plugin from the array with the following function I get a "memory could not be read" error from Windows. When there is only 1 plugin in the array, it works. When there are 2, it fails with that error. When there are 3 or more it seems to work also (altought if there are a lot of plugins it fails again).

int PluginManager::RemovePlugin(UINT ID)
{
    err = 0;
    UINT index = FindPlugin(ID);
    if(err == 0)
    {
        UINT k = 0;
        InternalPluginInfo* temp = new InternalPluginInfo[Count - 1];
        if(!temp)
        {
            err = 2;
            return FAILURE;
        }

        for(UINT i = 0; i < Count; i++)
        {
            if(Plugin[i].ID != ID)
            {
                temp[k].ID = Plugin[i].ID;
                temp[k].Flags = Plugin[i].Flags;
                temp[k].Module = Plugin[i].Module;
                temp[k].Info = Plugin[i].Info;
                k++;
            }
        }

        if(Plugin[index].Info.PluginName)
            delete [] Plugin[index].Info.PluginName;
        if(Plugin[index].Info.PluginAuthor)
            delete [] Plugin[index].Info.PluginAuthor;

        if(Plugin[index].Info.Callback)
            (Plugin[index].Info.Callback)(cPluginQuit, 0, 0);

        FreeLibrary(Plugin[index].Module);

        delete [] Plugin;
        Plugin = temp;
        Count = k;

        return SUCCESS;
    }

    err = 1;
    return FAILURE;
}

I think the error occurs beacuse of this line temp[k].Module = Plugin[i].Module; , but I'm not sure. When I remove it from the code, everything seems to work fine.

Thanks in advance.

this is obviously a c++ program so why don't you use a c++ container such as <map> to house the plugins? Other than that, its hard to say what your problem is because you did not post enough code. It would be helpful if you just zipped up all the files and attached it to your post.

I've attached the whole source code (Code-Blocks project, both sources and binaries, plus a sample plugin included).

I'm still learning C++, but I didn't heard of C++ containers yet :rolleyes:. I just searched about them on the web and found out they're part of the Standard Template Library (heard of C++ templates, but know little about them). Could you please point me to some good C++ STL/Templates tutorials ?

Thanks for helping me.

Here is one you should bookmark.

Plugin.h should be using std::string objects instead of char* -- it will make your life a lot easier because you don't need to allocate memory for those strings. Look over your code and see where else you can substitute std::string for char*.

typedef struct _PluginInfo
{
	std::string PluginName;
	std::string PluginAuthor;
	int Flags;
	PluginCallback Callback;

} PluginInfo;

Here is an example of how to use map. All it does is associate a number with an instance of PluginInfo object.

#pragma warning(disable: 4786)
#include <windows.h>
#include <iostream>
#include <string>
#include <map>

typedef enum _RequestCode
{
	cPluginInit = 1,
	cPluginQuit = 2

} RequestCode;

typedef long (*ServiceFunc)(UINT, RequestCode, UINT_PTR, ULONG_PTR);
typedef long (*PluginCallback)(RequestCode, UINT_PTR, ULONG_PTR);

typedef struct _PluginInfo
{
	std::string PluginName;
	std::string PluginAuthor;
	int Flags;
	PluginCallback Callback;

} PluginInfo;

std::map<UINT,PluginInfo*>  theList;



int main()
{
	PluginInfo* info = new PluginInfo;
	theList[1] = info;
	PluginInfo* pinfo  = theList[1];
	return 0;
}

Thanks. The problem was indead caused by PluginName and PluginAuthor not being allocated. I was expecting them to be allocated by the dll. They're now allocated by the application and the dll only has to fill them.

This article has been dead for over six months. Start a new discussion instead.