Attempted to read or write protected memory when using reflection to call dll functions

763 Views Asked by At

I have made a plugin system that uses reflection to call functions in a plugin. A plugin has to implement the IPlugin interface to be used. In the application which uses the plugins the plugin instance is created with the following code:

    Assembly currentAssembly = Assembly.LoadFrom(startInfo.PluginAssemblyPath);
    Type[] types = currentAssembly.GetTypes();
    IPlugin pluginInstance = null;

    foreach (Type type in types)
    {
        if (type.FullName == startInfo.PluginTypeName)
        {
            pluginInstance = (IPlugin)Activator.CreateInstance(type);
        }
    }

    if (pluginInstance == null)
    {
        throw new Exception("Plugin loader error: Could not instantiate plugin: " + startInfo.ToString());        }

    return pluginInstance;

I have made a plugin that uses some unmannaged dll's. When I call the IPlugin interface functions in a test project in the plugin solution everything works fine. But when I call the plugin via the plugin instance made in the code shown above I get the System.AccessViolationException: Attempted to read or write protected memory error when calling functions in the unmannaged dll's.

The unmannaged dll's are c++ dll's made by a third party. I tried enabling native code debugging but i do not have the .pdb files.

I am not sure why this is happening, is this because of the reflection? Or can there be other causes?

Edit: In the stack I can see the unmannaged function being called:

[MarshalAs(UnmanagedType.LPStr)]
private readonly StringBuilder sb = new StringBuilder(256);

[DllImport("x.dll", EntryPoint = "xLib")]
static extern int _xLib(int a1, int a2, int a3, int a4, int a5, int a6, [Out]StringBuilder str);

The exception is thrown when calling the _xLib function.

Edit: Somewhere in this _xLib function the following function is called:

handle = x_Open();

which is in an other dll and is defined as:

DllExport x_Handle *x_Open();

As soon as anything in the handle is used like:

"%s", handle->x.string

The exception is thrown. I still do not understand why this is working in the test project and not when I am using it in the app as a plugin.

2

There are 2 best solutions below

0
On BEST ANSWER

Well after some intensive debugging I found the problem was the handle having some wrong address which caused the violation. The cause of the address being wrong was the x_open function loaded yet another dll with the LoadLibraryA function. This dll was not in the same directory as the executable file so it was not found.

I solved it by adding the directory of this last dll to the environment path.

2
On

Maybe you have to pin the StringBuilder to allow unmanaged code to interact with it.

Pinned object is one that is not allowed to move. The garbage collector is normally compacting the memory in that it moves all objects to "one or more clusters". This is to create large chunks of free space.

This basically means if someone else (outside) has a pointer to the memory address of an object, this may point to random content - as the object has moved.

Pinning an object tells the GC to NOT MOVE IT. This is normally useless and ONLY makes sense when working with pointers - like when using PInvoke... and I can see a pointer to a StringBuilder instance in _xlib function