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):
runtimeVersion="v1.4"
attribute in the DLL manifest clrClass
element specifically)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.
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