How do you reference a WCF service in a COM interop enabled DLL?
Problem Summary : I have a C# DLL that is COM interop enabled/visible. This C# DLL has a service reference to a WCF service. When I instantiate the WCF service in the C# code, COM interop returns a error HRESULT (0x80131509).
Problem Details :
There are three components in my solution. The first is an unmanaged C++ application. This C++ application needs to communicate with a WCF service. The approach I decided on was to make a C# middle layer between the C++ application and the WCF service. The C# layer would be COM interop enabled/visible so that the C++ application could call into it and the C# code would handle talking to the WCF services. The C++ side would never need to know about the WCF services; the COM interop call would be a black box as far as it was concerned.
The problem arises when I try to instantiate the WCF service client in the C# code. To facilitate testing, I made a Test() method in the C# DLL. Calling Test() would simply return a hard-coded test string. This works. I am able to start up the C++ application, which calls into the C# DLL via COM interop, and the test string is returned. The HRESULT is S_OK. Now, if I change the Test() method by adding a single line that simply instantiates the WCF client, the COM interop call now returns an HRESULT of 0x80131509.
The only clue I have is that when I compile the C# DLL, I get the following warning:
warning : Type library exporter warning processing '[my WCF service]'. Warning: Type library exporter encountered a type that derives from a generic class and is not marked as [ClassInterface(ClassInterfaceType.None)]. Class interfaces cannot be exposed for such types. Consider marking the type with [ClassInterface(ClassInterfaceType.None)] and exposing an explicit interface as the default interface to COM using the ComDefaultInterface attribute.
I don't know why it is giving me a warning about exporting the WCF service type. I was hoping that by using the C# middle layer, it could isolate the existence of the WCF services from the C++ application.
So what is the trick for using WCF services in a DLL that is COM enabled/visible?
After several days of agony, a solution has been found, though it feels more like a work-around than a real solution.
I found a clue when I realized that when attempting to instantiate the WCF service in the C# code, an exception was thrown. After trapping the exception on the C++ side of things (a CAtlException to be exact) and looking at the HRESULT code, I determined that the C++ program was complaining because it couldn't find the WCF service bindings. Wait, what? Somewhat unbelieving, I created a .exe.config file and put it in the same directory as the executable. The .exe.config file basically contained the contents of the app.config from the WCF service project, plus an additional client
tag in the system.serviceModel
section that held a single endpoint
tag pointing to the address of the WCF service. Everything worked fine with that in place.
It seems wrong to me though. Why should the C++ program need to know that? Just thinking logically, the C# COM interop should separate that knowledge and act as a barrier, totally encapsulating the WCF layer. By forcing the C++ program to know about the underlying structure, it defeats that encapsulation and makes everything all a little more...inelegant. It is entirely possible that I don't know how the messy innards of COM interop work, so maybe it all makes sense to someone.
链接地址: http://www.djcxy.com/p/81314.html上一篇: COM对象中的回调