delphic#-4.0dllsharpdevelopside-by-side

Error COR_E_NEWER_RUNTIME when creating COM class from side by side assembly


I have the following situation:

Delphi application code (console executable):

program TestSideBySide2;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  mscorlib_TLB in 'mscorlib_TLB.pas',
  TestSideBySide2_TLB in 'TestSideBySide2_TLB.pas';

var
   sideBySide : TestSideBySide2_TLB._SideBySideClass;
   intfSideBySide : TestSideBySide2_TLB.ISideBySideClass;
   res : HRESULT;

begin
  try
      sideBySide := TestSideBySide2_TLB.CoSideBySideClass.Create();
      res := sideBySide.QueryInterface(IID_ISideBySideClass,intfSideBySide);

      Writeln(intfSideBySide.Version());

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

The imported 'TestSideBySide2_TLB.pas' was generated from the DLL using the TLIBIMP.exe tool.

Here's the application manifest that would be linked to the Delphi application as resource:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"
          xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
  <assemblyIdentity 
    type="win32"
    name="TestSideBySide.exe"
    version = "1.0.0.0" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="TestSideBySide2"
        version="1.0.0.0" />
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

C# DLL code (compiled using SharpDevelop)

using System;
using System.Reflection;
using System.Runtime.InteropServices;

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("07F9C367-BFA4-45AD-8A60-689096BD7AA9")]

namespace TestSideBySide2
{

    /// <summary>
    /// Exposed interface.
    /// </summary>
    [Guid("49D49031-12D8-40B5-85FA-B42133FD7DD0")]
    public interface ISideBySideClass
    {
        string Version();
    }

    /// <summary>
    /// Implementation of exposed interface.
    /// </summary>
    [Guid("A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E")]
    public class SideBySideClass : ISideBySideClass
    {
        public string Version()
        {
            return "1.0.0-C#";
        }
    }
}

And the assembly manifest (also linked as a resource into the DLL):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" 
  manifestVersion="1.0">
    <assemblyIdentity
                type="win32"
                name="TestSideBySide2"
                version="1.0.0.0" />
    <clrClass
                clsid="{A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}"
                progid="TestSideBySide2"
                threadingModel="Both"
                name="TestSideBySide2.SideBySideClass" >
    </clrClass>
</assembly>

Everything fairly simple so far. The Delphi application can resolve the bindings and the DLL will be loaded. But the line

sideBySide := TestSideBySide2_TLB.CoSideBySideClass.Create();

fails with the exception

EOleSysError: OLE-Error 8013101B, ClassID: {A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}

The error code resolves to COR_E_NEWER_RUNTIME.


I checked the .NET runtime version the DLL was build for, and that's .NET 4.0 (which is available on my Windows 10 environment).

Then I tried to build the DLL for older runtime versions (2.0, 3.0, 3.5), and for each of them it worked just fine.


Of course I've been researching what could be the problem, and here's what I found so far promising to remedy the problem (but didn't):

Currently I'm out of ideas what else could be done. Any further resources I found on the internet merely point to one of the proposals I've listed above.

What else could I've been overlooking there?


Update:

A colleague mentioned it could be a Delphi oddness and calling from unmanaged code.

We're using Embarcadero Seattle Delphi 10.


Solution

  • I solved the problem with help of the information found here:

    Runtime Versions and Errors 0x80131700 and 0x8013101b

    I had already done an attempt to add the .NET CLR version at the assembly manifest of the DLL. This can be done per class in the clrClass section. What I didn't knew was, that the runtimeVersion attribute must be fully qualified.

    The full clrClass section looks like this now:

    <clrClass
                clsid="{A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}"
                progid="TestSideBySide2"
                threadingModel="Both"
                name="TestSideBySide2.SideBySideClass" 
                runtimeVersion="v4.0.30319">
    </clrClass>
    

    According to the document linked above the version entries for other CLR versions should be:

    • v1.0.3705
    • v1.1.4322
    • v2.0.50727
    • v4.0.30319