Używanie biblioteki COM z C # bez biblioteki typów
Muszę użyć komponentu COM (dll) opracowanego przed wiekami w Delphi. Problem polega na tym, że dll nie zawiera biblioteki typów ... i każda funkcja interop (np. TlbImp) w .NET wydaje się polegać na TLB. Komponent został użyty w programach Delphi tutaj od wielu lat bez problemów, ponieważ „Nie ma większego problemu z używaniem obiektów COM z Delphi, ponieważ znamy interfejsy” (cytuj programista Delphi).
Czy jest jakiś sposób, w jaki mogę użyć tej biblioteki DLL z c # bez TLB? Próbowałem użyć biblioteki DLL jako niezarządzanej, ale jedynym sposobem jej eksportu jestDllUnregisterServer
, DllRegisterServer
, DllCanUnloadNow
iDllGetClassObject
. Znam nazwy klas i funkcji, z których zamierzam korzystać, jeśli może to pomóc.
AKTUALIZACJA: Próbowałem zaimplementować sugestię Jeffa, ale otrzymuję ten błąd:
„Nie można rzutować obiektu COM typu„ ComTest.ResSrvDll ”na typ interfejsu„ ComTest.IResSrvDll ”. Ta operacja nie powiodła się, ponieważ wywołanie QueryInterface wywołało składnik COM dla interfejsu z IID” {75400500-939F-11D4-9E44-0050040CE72C} 'nie powiodło się z powodu następującego błędu: Brak obsługi takiego interfejsu (wyjątek od HRESULT: 0x80004002 (E_NOINTERFACE)). ”
Oto co zrobiłem:
Mam tę definicję interfejsu od jednego z facetów z Delphi:
<code>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. </code>
Z tego stworzyłem ten interfejs
<code>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); } } </code>
I ta koklasa (dostałem przewodnika od delfinów)
<code>using System.Runtime.InteropServices; namespace ComTest { [ComImport] [Guid("75400503-939F-11D4-9E44-0050040CE72C")] public class ResSrvDll { } } </code>
AKTUALIZACJA
Rozwiązanie od Jeffa to sposób na to. Warto jednak zauważyć, że definicja interfejsu musi być zgodna ze składnikami COMdokładnie! to znaczy. ta sama kolejność, te same nazwiska itp.