【发布时间】:2010-11-05 11:38:36
【问题描述】:
我需要使用很久以前在 Delphi 中开发的 COM 组件(一个 dll)。问题是:dll 不包含类型库……而且 .NET 中的每个互操作功能(例如 TlbImp)似乎都依赖于 TLB。该组件已在 Delphi 程序中使用多年,没有出现任何问题,因为“使用 Delphi 的 COM 对象不是什么大问题,因为我们知道接口”(引用 Delphi 开发人员)。
有没有什么方法可以在没有 TLB 的情况下从 c# 使用这个 DLL?我尝试将 DLL 用作非托管的,但它导出的唯一方法是 DllUnregisterServer、DllRegisterServer、DllCanUnloadNow 和 DllGetClassObject。我知道我要使用的类和函数的名称,如果有帮助的话。
更新: 我已尝试实施 Jeff 的建议,但出现此错误:
“无法将类型为“ComTest.ResSrvDll”的 COM 对象转换为接口类型“ComTest.IResSrvDll”。此操作失败,因为对具有 IID 的接口的 COM 组件调用 QueryInterface '{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);
}
}
还有这个 coclass(从 delphi-guys 那里得到了指导)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
}
}
更新
Jeff 的解决方案就是解决问题的方法。不过值得注意的是,接口定义必须与 COM 组件完全匹配! IE。相同的顺序,相同的名称等。
【问题讨论】:
-
这个dll的源代码丢失了吗?
-
不,但 Delphi 开发人员目前非常支持,一想到要进入这个老庞然大物,他们就会翻白眼;-)