我有一个WCF服务,其合同如下:(操作合同是OneWay)
[ServiceContract()]
public interface IEmpUpdate
{
[OperationContract(IsOneWay = true)]
void SendEmpUpdate(int _empid);
}
我必须从COM DLL调用此SendEmpUpdate方法。我在网上搜索并找到了一些例子,但那是为了vb。我的COM组件是用C ++开发的。我按照相同的步骤在C ++中执行此操作。
我遵循的链接:
此链接说明了两种方法:
1.使用类型化合同来收集WCF服务 2.使用MEX端点获取WCF服务
我试过两种方式:(C ++)
第二种方式(使用MEX端点使用WCF服务)请参阅以下代码:
如果我将SendEmpUpdate的OperationContract IsOneWay更改为false,则第二种方式可以正常工作。如果它的真实,Invoke方法失败,HRESULT值为0x80131502(它似乎就像一个 ArgumentOutOfRangeException使用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);
}
第一种方法(使用类型合约使用WCF服务)请参阅以下代码:
在第一种方法中,CoGetObject失败,objEmp为空。
//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);
}
问题:
答案 0 :(得分:5)
首先......对不起你与COM打交道!
我们最近有机会使用来自C ++和VB6的4.0 WCF服务(通过httpBinding,尽管这不应该太重,取决于.NET的版本)。我遇到了你可能做过的同样的文章,坦率地说, COM Moniker goop是为了鸟类。我从未成功地以可靠的方式工作。可能我只是无知。
不幸的是,有一大堆基于COM的“传统”代码。
相反,我们非常成功地创建了一个具有实际WCF服务代理的外观的.NET程序集。我们通过.NET COM Interop公开了外观,然后委托给由Add Service Reference向导生成的内部代理clas。除了一些重复的代码之外,它还像冠军一样,同时允许下层客户端通过HTTP使用基于SOAP的端点。
查看MSDN Example COM Class,了解如何装饰将通过COM Interop公开的Facade类。它描述了您的类型需要暴露给COM感知客户端的神奇的属性。
基本大纲是
如果您没有“拥有”主机,您可能需要完全从Reading WCF Configuration from a Custom Location借用有关如何加载绑定和端点配置的提示,这些配置可能不在预期的mayapp.exe.config中。
不完全是你想要的答案,希望有这种经验的人会发布。
ž
答案 1 :(得分:0)
问题2的可能答案:在这种情况下,您的名字对象缺少其方案前缀“service:
”。