I want to call a DLL in my programming language of ‘choice’. The documentation surrounding this clearly states that it must be a 32-bit DLL written in C, C++ or Delphi. But I wanted to call a DLL written in C#. It goes on to mention that the default calling mode is cdecl.
So my question is: why would this be the case? Is there any way to make it think a C# DLL was written in C, C++ or Delphi?
2
That very problem is what COM was designed to address. I’ll leave it to my good friend Jeremiah Morrill to explain what the problem is:
I explained briefly how simple exporting regular “C” methods can be to
share code between DLLs and the application. I also explained how C++
classes get flattened and compiled down and also how they are seen to
your CPU (more or less). If C++ classes just get compiled to static
“C” methods, which can be exported from our DLL, is that not
sufficient to reuse and share classes across DLLs? Yes…but not
without some major caveats as this would come at a cost.
The first disadvantage of exporting a C++ class is you must use the same C runtime in all DLLs/exe involved. So if one DLL used MSVCRT7,
the caller of the DLL must be using MSVCRT7. The reason is different
versions of C runtimes manage the heap differently, so if DLL A tried
to free resources allocated by DLL B, memory corruption can occur.The second disadvantage is the same compiler version must be used. This is because different compilers mangle names differently. Name
mangling differences among compilers ensures a DLL built with
Microsoft would have completely different symbol names than a DLL
built with GCC. So when linking of your code occurs, the linker might
be looking for “??4MyWidget…” when the export is really
“MyWidget__Fi…”Third, if a large change of the base classes in DLL A are made, even without breaking API, then DLL B that uses the base classes must
be recompiled.Forth [sic], if you take the last three disadvantages into consideration, we have a very tight coupling between our DLLs. This
inhibits reusability of the module.Sometimes these issues are not an issue for a given project. This is
usually acceptable when the project is small, or an in house utility.
That’s totally fine. But let’s pretend Microsoft ignored these
problems. All developers would have to use the same compiler version.
Applications would have to be written for very specific versions of
Windows. This would be a complete nightmare for everyone.
Looking at those problems, COM is a simple solution for solving them. By exposing your C# dll to COM, you can call it from any other COM compliant language.
1
Your language of choice supports calling any native DLLs written in any language. It’s not really limited to those made with C, C++ or Delphi. You could call Fortran DLLs too, for example.
The problem is that the C# DLL is a managed DLL. That’s a completely different beast from a native DLL. You will need to put a bridging layer in between the C# and your code. Robert Giesecke’s Unmanaged Exports is one simple way to do that.