问题摘要:我有一个启用了COM互操作/可见的C#DLL。此C#DLL具有对WCF服务的服务引用。当我在C#代码中实例化WCF服务时,COM interop返回错误HRESULT(0x80131509)。
问题详情:
我的解决方案中有三个组件。第一个是非托管C ++应用程序。此C ++应用程序需要与WCF服务进行通信。我决定采用的方法是在C ++应用程序和WCF服务之间建立一个C#中间层。 C#层将启用COM互操作/可见,以便C ++应用程序可以调用它,C#代码将处理与WCF服务的通信。 C ++方面永远不需要了解WCF服务;就其而言,COM互操作呼叫将是一个黑盒子。
当我尝试在C#代码中实例化WCF服务客户端时出现问题。为了便于测试,我在C#DLL中创建了一个Test()方法。调用Test()只会返回一个硬编码的测试字符串。这有效。我能够启动C ++应用程序,它通过COM interop调用C#DLL,并返回测试字符串。 HRESULT是S_OK。现在,如果我通过添加一个简单实例化WCF客户端的单行来更改Test()方法,则COM互操作调用现在返回HRESULT为0x80131509。
我唯一的线索是,当我编译C#DLL时,我收到以下警告:
警告:键入库导出器警告处理'[my WCF service]'。警告:类型库导出器遇到的类型派生自泛型类,并且未标记为[ClassInterface(ClassInterfaceType.None)]。不能为这些类型公开类接口。考虑使用[ClassInterface(ClassInterfaceType.None)]标记类型,并使用ComDefaultInterface属性将显式接口公开为COM的默认接口。
我不知道为什么它会给我一个关于导出WCF服务类型的警告。我希望通过使用C#中间层,它可以将CCF应用程序的存在与C ++应用程序隔离开来。
那么在启用COM /可见的DLL中使用WCF服务的技巧是什么?
答案 0 :(得分:1)
经过几天的痛苦之后,我们发现了一种解决方案,尽管它更像是一种解决方案,而不是真正的解决方案。
当我意识到当尝试在C#代码中实例化WCF服务时,我发现了一个线索,引发了一个异常。在事物的C ++方面捕获异常(确切地说是CAtlException)并查看HRESULT代码后,我确定C ++程序抱怨,因为它无法找到WCF服务绑定。等等,什么?有点不相信,我创建了一个.exe.config文件并将其放在与可执行文件相同的目录中。 .exe.config文件基本上包含来自WCF服务项目的app.config的内容,以及client
部分中包含指向单个system.serviceModel
标记的其他endpoint
标记WCF服务的地址。一切都运行良好。
虽然我觉得不对。为什么C ++程序需要知道?只是从逻辑上思考,C#COM互操作应该将这些知识分开并充当障碍,完全封装WCF层。通过强制C ++程序了解底层结构,它破坏了封装并使一切都变得更加......不优雅。我完全有可能不知道COM互操作的混乱内部是如何工作的,所以也许这对某人来说都是有道理的。