我需要使用一个在很久以前用Delphi开发的COM组件(dll)。问题是:该dll不包含类型库...而且.NET中的每个Interop功能(例如TlbImp)似乎都依赖于TLB。该组件已经在这里的Delphi程序中使用了很多年,没有问题,因为“从Delphi使用COM对象并不是太大的问题,因为我们知道接口”(引用Delphi开发人员的话)。
有没有办法在没有TLB的情况下从C#使用此DLL?我尝试将DLL用作非托管代码,但它导出的唯一方法是DllUnregisterServer、DllRegisterServer、DllCanUnloadNow和DllGetClassObject。如果这可以有所帮助,我知道要使用的类和函数的名称。
更新: 我尝试了Jeff的建议,但我收到了以下错误消息:
“无法将类型为“ComTest.ResSrvDll”的COM对象强制转换为接口类型“ComTest.IResSrvDll”。此操作失败,因为针对IID“{75400500-939F-11D4-9E44-0050040CE72C}”的COM组件上的QueryInterface调用失败,原因是出现以下错误:不支持此类接口 (HRESULT 为 0x80004002 (E_NOINTERFACE))。”
这是我做的事情:
我从其中一个Delphi开发人员那里得到了这个接口定义:
有没有办法在没有TLB的情况下从C#使用此DLL?我尝试将DLL用作非托管代码,但它导出的唯一方法是DllUnregisterServer、DllRegisterServer、DllCanUnloadNow和DllGetClassObject。如果这可以有所帮助,我知道要使用的类和函数的名称。
更新: 我尝试了Jeff的建议,但我收到了以下错误消息:
“无法将类型为“ComTest.ResSrvDll”的COM对象强制转换为接口类型“ComTest.IResSrvDll”。此操作失败,因为针对IID“{75400500-939F-11D4-9E44-0050040CE72C}”的COM组件上的QueryInterface调用失败,原因是出现以下错误:不支持此类接口 (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);
}
}
而且这个 coclass(从 Delphi 开发者那里获取了 guid)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
}
}
更新
Jeff的解决方案是正确的。需要注意的是,接口定义必须与COM组件完全匹配!即相同的顺序、相同的名称等。