这是示例界面
[Guid(XXCryptService.InterfaceId),ComVisible(true)/*,InterfaceType(ComInterfaceType.InterfaceIsIUnkNown)*/] public interface IXXCryptService { [dispId(1)] string Encrypt(string password,string key); [dispId(2)] string Decrypt(string password,string key); }
和班级
[ClassInterface(ClassInterfaceType.None)] [Guid(XXCryptService.ClassId),ComVisible(true)] public class XXCryptService : ReferenceCountedobject,IXXCryptService { internal const string ClassId = "C5F6938B-5593-4872-B8C7-B47EE33EABCD"; internal const string InterfaceId = "6990FF5F-22E2-4032-8B98-36115DBCEFFF"; [Editorbrowsable(EditorbrowsableState.Never)] [ComregisterFunction()] public static void Register(Type t) { try { COMHelper.RegasmRegisterLocalServer(t); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } } [Editorbrowsable(EditorbrowsableState.Never)] [ComUnregisterFunction()] public static void Unregister(Type t) { try { COMHelper.RegasmUnregisterLocalServer(t); } catch (Exception ex) { Console.WriteLine(ex.Message); throw ex; } } public string Encrypt(string password,string key) { return "Encrypted"; } public string Decrypt(string password,string key) { return "Decrypted"; } }
该程序运行,但是当客户端连接它时,在服务器触发ObjectClassFactory上的CreateInstance后,它在客户端崩溃,并使用Marshal.GetComInterfaceForObject(new XXCryptService(),typeof(IXXCryptService))返回ppvObject上的对象并返回0.
在.NET上运行客户端会触发“无法将类型为’COMTest.XXCryptService’的COM对象’转换为接口类型’COMTest.IXXCryptService’.此操作失败,因为QueryInterface调用COM组件上的IID为{6990FF5F-的接口22E2-4032-8B98-36115DBCEFFF}由于以下错误而失败:找不到元素.(HRESULT异常:0x8002802B(TYPE_E_ELEMENTNOTFOUND)).“.
[Guid("6990FF5F-22E2-4032-8B98-36115DBCEFFF")] //[InterfaceType(ComInterfaceType.InterfaceIsDual)] interface IXXCryptService { [dispId(1)] string Encrypt(string password,string key); } [ComImport,Guid("C5F6938B-5593-4872-B8C7-B47EE33EABCD")] class XXCryptService { } class Program { static void Main(string[] args) { XXCryptService cs = new XXCryptService(); IXXCryptService ics = (IXXCryptService) cs; Console.WriteLine(ics.Encrypt("Test","Test")); Console.ReadKey(); } }
在Delphi上运行客户端会在EIntfCastError中触发异常,并显示消息“Interface not supported”.使用“导入类型库”导入COM并像这样使用.
procedure TForm1.FormCreate(Sender: TObject); begin FCrypter := CoXXCryptService.Create; end;
TLB界面看起来像这样
IXXCryptService = interface(Idispatch) ['{6990FF5F-22E2-4032-8B98-36115DBCEFFF}'] function Encrypt(const password: WideString; const key: WideString): WideString; safecall; function Decrypt(const password: WideString; const key: WideString): WideString; safecall; end; // *********************************************************************// // dispIntf: IXXCryptServicedisp // Flags: (4416) Dual OleAutomation dispatchable // GUID: {6990FF5F-22E2-4032-8B98-36115DBCEFFF} // *********************************************************************// IXXCryptServicedisp = dispinterface ['{6990FF5F-22E2-4032-8B98-36115DBCEFFF}'] function Encrypt(const password: WideString; const key: WideString): WideString; dispid 1; function Decrypt(const password: WideString; const key: WideString): WideString; dispid 2; end;
我已通过注册表检查,一切似乎都已正确注册,所以我不明白为什么我应该得到这个问题.
这里有人对可能出现的问题有任何疑问吗?
编辑:在64位编译客户端,这是正常的.此外,它引用了错误的路径,在我调整它后,我在.NET x86客户端上遇到了不同的错误
此操作失败,因为由于以下错误,对IID为“{6990FF5F-22E2-4032-8B98-36115DBCEFFF}”的接口的COM组件的QueryInterface调用失败:加载类型库/ DLL时出错. (来自HRESULT的异常:0x80029C4A(TYPE_E_CANTLOADLIBRARY))
解决方法
为了解决这个问题,我不得不暂时将可执行文件(使用相同的路径)编译为32位,运行32位regasm(使用/ tlb:..),然后编译回64位,运行64位regasm(使用/ tlb:..再次),现在它适用于32位和64位对64位可执行文件.
CSExeComServer有一个注册和取消注册方法,它手动删除InprocServer32密钥并添加LocalServer32.为了确保这个工作正常,我将改变这个,检测它是否在64位系统上注册,然后让它在那里正确注册.当我完成后,我会将我做的更改发布到注册方法中.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。