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?