Мне нужно использовать COM-компонент (dll), разработанный в Delphi много лет назад. Проблема в том, что dll не содержит библиотеки типов ... и каждая функция взаимодействия (например, TlbImp) в .NET, похоже, полагается на TLB. Компонент использовался здесь в программах Delphi в течение многих лет без проблем, потому что «Использование COM-объектов из Delphi не представляет большой проблемы, потому что мы знаем интерфейсы» (цитата разработчика Delphi).
Есть ли способ использовать эту DLL из c # без TLB? Я пытался использовать DLL как неуправляемую, но единственным методом, который она экспортирует, являются DllUnregisterServer
, DllRegisterServer
, DllCanUnloadNow
и DllGetClassObject
. Я знаю имена классов и функций, которые я собираюсь использовать, если это поможет.
UPDATE:
Я пытался реализовать предложение Джеффа, но я получаю эту ошибку:
"Невозможно привести объект COM типа ComTest.ResSrvDll к типу интерфейса ComTest.IResSrvDll. Эта операция завершилась неудачно, поскольку QueryInterface вызывает компонент COM для интерфейса с IID" {75400500-939F- 11D4-9E44-0050040CE72C} 'не удалось из-за следующей ошибки: такой интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)). "
Вот что я сделал:
Я получил это определение интерфейса от одного из Delphi-парней:
unit ResSrvDllIf;
interface
type
IResSrvDll = interface
['{75400500-939F-11D4-9E44-0050040CE72C}']
procedure clearAll;
function ResObjOpen(const aClientID: WideString; const aClientSubID: WideString;
const aResFileName: WideString; aResShared: Integer): Integer; {safecall;}
...
end;
implementation
end.
Из этого я сделал этот интерфейс
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400500-939F-11D4-9E44-0050040CE72C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IResSrvDll
{
int ResObjOpen(string aClientID, string aClientSubID, string aResFileName, int aResShared);
}
}
И этот кокласс (получил гид от дельфи-парней)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
}
}
UPDATE
Решение от Джеффа - это способ сделать это. Однако стоит отметить, что определение интерфейса должно соответствовать COM-компонентам , в точности ! то есть. тот же порядок, те же имена и т. д.