У меня есть следующая ситуация:
- Собственное приложение Delphi должно вызывать COM-интерфейс из C # DLL.
- Я хочу взаимодействовать с приложением и DLL без регистрации C # DLL (бок о бок)
Код приложения Delphi (исполняемый файл консоли):
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.
Импортированный 'TestSideBySide2_TLB.pas'
был создан из DLL с помощью инструмента TLIBIMP.exe
.
Вот манифест приложения, который будет связан с приложением Delphi как ресурс:
<?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 (скомпилирован с помощью 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#";
}
}
}
И манифест сборки (также связанный как ресурс с 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>
Пока все довольно просто. Приложение Delphi может разрешить привязки, и DLL будет загружена. Но линия
sideBySide := TestSideBySide2_TLB.CoSideBySideClass.Create();
Терпит неудачу за исключением
EOleSysError: OLE-Error 8013101B, ClassID: {A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}
Код ошибки переходит в COR_E_NEWER_RUNTIME
.
Я проверил версию среды выполнения .NET, для которой была создана DLL, и это .NET 4.0 (которая доступна в моей среде Windows 10).
Затем я попытался создать DLL для более старых версий среды выполнения (2.0, 3.0, 3.5), и для каждой из них она работала нормально.
Конечно, я исследовал, в чем может быть проблема, и вот что я нашел до сих пор многообещающим для решения проблемы (но не сделал этого):
- Не удается заставить работать VB.NET DLL, на которую ссылается клиент VB6, в сценарии reg-free
- Как: настроить COM-компоненты на основе .NET Framework для активации без регистрации (с использованием атрибута
runtimeVersion="v1.4"
в элементе манифеста DLLclrClass
)
В настоящее время у меня нет идей, что еще можно сделать. Любые другие ресурсы, которые я нашел в Интернете, просто указывают на одно из предложений, которые я перечислил выше.
Что еще я мог там пропустить?
Обновить:
Коллега упомянул, что это может быть странность Delphi и вызов из неуправляемого кода.
Мы используем Embarcadero Seattle Delphi 10.
1 ответ
Я решил проблему с помощью информации, найденной здесь:
Версии среды выполнения и ошибки 0x80131700 и 0x8013101b
Я уже предпринял попытку добавить версию .NET CLR в манифест сборки библиотеки DLL. Это можно сделать для каждого класса в разделе clrClass
. Я не знал, что атрибут runtimeVersion
должен быть полностью определен.
Полный раздел clrClass
теперь выглядит так:
<clrClass
clsid="{A0BDB20B-A6E4-4A36-A64C-CC9186DD1C3E}"
progid="TestSideBySide2"
threadingModel="Both"
name="TestSideBySide2.SideBySideClass"
runtimeVersion="v4.0.30319">
</clrClass>
Согласно документу, указанному выше, записи версий для других версий CLR должны быть:
- v1.0.3705
- v1.1.4322
- v2.0.50727
- v4.0.30319
Похожие вопросы
Новые вопросы
delphi
Delphi - это язык для быстрой разработки собственных приложений для Windows, macOS, Linux, iOS и Android с использованием Object Pascal. Название относится к языку Delphi, а также к его библиотекам, компилятору и IDE, которые используются для помощи в редактировании и отладке проектов Delphi.
COR_E_NEWER_RUNTIME
.