I have a WCF Service which has a contract like this: (the operation contract is OneWay)
[ServiceContract()]
public interface IEmpUpdate
{
[OperationContract(IsOneWay = true)]
void SendEmpUpdate(int _empid);
}
I have to call this SendEmpUpdate method from a COM DLL. I searched in the web and found some examples but that was for vb. My COM component was developed in C++. I followed the same steps for doing it in C++.
The Link which I followed:
This link explains about two ways of doing it:
1.Consuming a WCF service using a typed contract 2.Consuming a WCF service using a MEX endpoint
I tried in both ways: (C++)
The 2nd way (Consuming a WCF service using a MEX endpoint) please see the below code:
The 2nd way works fine if I change OperationContract IsOneWay to false for SendEmpUpdate. If its true the Invoke method is failing with HRESULT value 0x80131502 (it seems to be like a ArgumentOutOfRangeException uses the HRESULT COR_E_ARGUMENTOUTOFRANGE)
//Importing the tlb:
#import "Employee.tlb" no_namespace named_guids
//Creating the moniker string:
LPTSTR moniker = L"service:mexaddress=net.tcp://localhost:11234/Employee/mex, "
L"address=net.tcp://localhost:11234/Employee, "
L"contract=IEmpUpdate, "
L"binding=nettcpEmpUpdate, ";
//Get the Object:
HRESULT hr = S_FALSE;
IDispatch* objWsc;
hr = CoGetObject(moniker, NULL, IID_IDispatch, (void**)&objWsc);
if (FAILED(hr))
{
Message(TEXT("Client: CoGetObject"), hr);
return(hr);
}
DISPID dispid;
BSTR pOperation = L"SendEmpUpdate";
hr = objWsc->GetIDsOfNames(
IID_NULL,
&pOperation,
1,
LOCALE_SYSTEM_DEFAULT,
&dispid);
if (FAILED(hr))
{
Message(TEXT("Client: GetIDsOfNames"), hr);
return(hr);
}
DISPPARAMS empIDs;
VARIANTARG varData[1];
empIDs.rgvarg = &varData[0];
VariantInit(&empIDs.rgvarg[0]);
empIDs.rgvarg[0].vt = VT_I4;
empIDs.rgvarg[0].lVal = 564234;
empIDs.cArgs = 1;
empIDs.cNamedArgs = 0;
empIDs.rgdispidNamedArgs = NULL;
VARIANT result;
//VariantInit(&result);
UINT argErr = 0;
EXCEPINFO pExcepInfo;
memset(&pExcepInfo, 0, sizeof(EXCEPINFO));
hr = objWsc->Invoke(
dispid,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_METHOD,
&empIDs, &result, &pExcepInfo, &argErr);
if (FAILED(hr))
{
Message(TEXT("Client: Invoke"), hr);
return(hr);
}
The 1st method (Consuming a WCF service using a typed contract) please see the below code:
In the 1st method CoGetObject is failing objEmp is null.
//Importing the tlb:
#import "Employee.tlb" no_namespace named_guids
//Creating the moniker string:
LPTSTR moniker = L"address=net.tcp://localhost:11234/Employee, "
L"contract={52DEEE76-0BAF-31D8-A48B-DA2C50FA2753}, "
L"binding=nettcpEmpUpdate ";
//Get the Object:
HRESULT hr = S_FALSE;
IEmpUpdate* objEmp;
hr = CoGetObject(moniker, NULL, __uuidof(IEmpUpdate), (void**)&objEmp);
if (FAILED(hr))
{
Message(TEXT("Client: CoGetObject"), hr);
return(hr);
}
Questions:
First off...sorry your dealing with COM!
We had the occasion recently to consume a 4.0 WCF service (via httpBinding, though that shouldn't matter much, depending on version of .NET) from both C++ and VB6. I came across the same article(s) you probably did, and frankly, the COM Moniker goop is for the birds. I was never successful in getting it working in a reliable fashion. Could be I'm just ignorant.
Unfortunately, there is a pooh ton of 'legacy' code out there that is built on COM.
Instead, we were very successful in creating a .NET assembly with a facade to the actual WCF service proxy. We exposed the facade via .NET COM Interop and then delegated to the internal proxy clas, which was generated by Add Service Reference wizard. Beyond a little duplicated code, it worked like a champ while allowing downlevel clients to consume a SOAP based endpoint over HTTP.
Check out MSDN Example COM Class for how to decorate your facade class that will be exposed via COM Interop. It describes the magic sprinkle of attributes your types will need to be exposed to a COM aware client.
Basic outline is
You might need to completely borrow tips from Reading WCF Configuration from a Custom Location on how to load up binding, and endpoint, configuration that might not be in the expected mayapp.exe.config if you don't 'own' the host.
Not exactly the answer your looking for, hopefully someone with the this experience will post.
Z
Possible answer to question 2: your moniker is missing its scheme prefix "service:
" in this case.
User contributions licensed under CC BY-SA 3.0