我需要使用很久以前用 Delphi 开发的 COM 组件(dll)。问题是:dll 不包含类型库…….NET 中的每个互操作功能(例如 TlbImp)似乎都依赖于 TLB。该组件已在此处的 Delphi 程序中使用多年,没有出现任何问题,因为“使用 Delphi 的 COM 对象不是什么大问题,因为我们知道接口(interface)”(引用 Delphi 开发人员的话)。
有什么方法可以在没有 TLB 的情况下从 c# 使用此 DLL?我试过将 DLL 用作非托管,但它导出的唯一方法是 DllUnregisterServer
、DllRegisterServer
、DllCanUnloadNow
和 DllGetClassObject
。我知道我将要使用的类和函数的名称,如果这有任何帮助的话。
更新: 我已尝试实现 Jeff 的建议,但出现此错误:
“无法将‘ComTest.ResSrvDll’类型的 COM 对象转换为接口(interface)类型‘ComTest.IResSrvDll’。此操作失败,因为 COM 组件上的 QueryInterface 调用用于 IID 为‘{75400500-939F- 11D4-9E44-0050040CE72C}' 由于以下错误而失败:不支持此类接口(interface)(HRESULT 异常:0x80004002 (E_NOINTERFACE))。”
这是我所做的:
我从一个 Delphi 专家那里得到了这个接口(interface)定义:
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 那里得到了 guid)
using System.Runtime.InteropServices;
namespace ComTest
{
[ComImport]
[Guid("75400503-939F-11D4-9E44-0050040CE72C")]
public class ResSrvDll
{
}
}
更新
Jeff 的解决方案就是实现它的方法。不过,值得注意的是,接口(interface)定义必须完全匹配 COM 组件! IE。相同的顺序、相同的名称等。
最佳答案
您只需要 CLS_ID 和接口(interface) ID。我在我的博客上写了这个具体问题:
关于c# - 在没有类型库的情况下使用 C# 中的 COM dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1037786/