C# DllImport re-use with different DLL names

48 Views Asked by At

I have a native library that provides some functions, e.g.:

CONSTBUFFER_HANDLE CONSTBUFFER_Create(const unsigned char* source, uint32_t size);

We'll call that "my_lib".

And from C# I can call it by exposing a DllImport like this:

[DllImport("my_dll1.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern IntPtr CONSTBUFFER_Create(IntPtr source, uint size);

But, That native library is linked into multiple DLL's. And I have different C# code that interfaces with different DLL's, but this code in my_lib should be accessed via different DLL's depending on the C# module.

So for example I have C# module A which uses my_dllA.dll for all the native code, and my_dllA links to my_lib. And then C# module B uses my_dllB.dll for native code. I could have a my_lib.dll with this my_lib code, but the code in my_lib heap allocates memory which can be freed by other functions (basically it's reference counted in the C code). So I can run into issues if I call CONSTBUFFER_Create from my_lib.dll and then some_other_function_which_frees_the_buffer from my_dllA.dll.

I wanted to do something like this:

    internal class InteropDefs
    {
        protected const string nativeDll = "my_dllA.dll";

        [DllImport(nativeDll, CallingConvention = CallingConvention.Cdecl)]
        internal static extern IntPtr CONSTBUFFER_Create(IntPtr source, uint size);
    }

    internal class MyInterop
    {
        public IntPtr ConstbufferCreate(Intptr source, uint size)
        {
            return InteropDefs.CONSTBUFFER_Create(source, size);
        }
    }

And was hoping I could then re-use InteropDefs with different nativeDll values, but that doesn't seem possible:

    internal class InteropDefs
    {
        protected const string nativeDll = "my_dllA.dll";

        [DllImport(nativeDll, CallingConvention = CallingConvention.Cdecl)]
        internal static extern IntPtr CONSTBUFFER_Create(IntPtr source, uint size);
    }

    internal class InteropDefsB : InteropDefs
    {
        nativeDll = "my_dllB.dll"; // somehow... doesn't seem to be any way to override this via static constructor or anything
    }

    internal class MyInterop<InteropDefsType> // I wish...
    {
        public IntPtr ConstbufferCreate(Intptr source, uint size)
        {
            return InteropDefsType.CONSTBUFFER_Create(source, size); // would be nice... but CS0704 error
        }
    }

So I guess the next best thing I can almost do is:

    internal class InteropDefsA
    {
        [DllImport("my_dllA.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern IntPtr CONSTBUFFER_Create(IntPtr source, uint size);
    }

    // Don't love that all the signatures need to be repeated...
    internal class InteropDefsB
    {
        [DllImport("my_dllB.dll", CallingConvention = CallingConvention.Cdecl)]
        internal static extern IntPtr CONSTBUFFER_Create(IntPtr source, uint size);
    }

    internal class MyInterop
    {
        public IntPtr ConstbufferCreate(Intptr source, uint size)
        {
            return /*But how can I select InteropDefsA vs. InteropDefsB here?*/ .CONSTBUFFER_Create(source, size);
        }
    }

Is there anything that can be done like this, or am I stuck between either duplicating the function definitions for each DLL or using GetProcAddress?

0

There are 0 best solutions below