我有一个WCF服务,它有这样的合同:(运营合同是OneWay)
[ServiceContract()]
public interface IEmpUpdate
{
[OperationContract(IsOneWay = true)]
void SendEmpUpdate(int _empid);
}
Run Code Online (Sandbox Code Playgroud)
我必须从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);
}
Run Code Online (Sandbox Code Playgroud)
第一种方法(使用类型化合约使用WCF服务)请参阅以下代码:
在第一种方法中,CoGetObject失败,objEmp为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);
}
Run Code Online (Sandbox Code Playgroud)
问题:
首先......对不起你与COM打交道!
我们最近有机会使用来自C++和VB6的4.0 WCF服务(通过httpBinding,尽管这应该不重要,具体取决于.NET的版本).我偶然发现了你可能做的同一篇文章,坦率地说,COM Moniker goop是为了鸟类.我从未成功地以可靠的方式工作.可能我只是无知.
不幸的是,有一大堆基于COM的"遗留"代码.
相反,我们非常成功地创建了具有实际WCF服务代理的外观的.NET程序集.我们通过.NET COM Interop公开了外观,然后委托给由Add Service Reference向导生成的内部代理clas.除了一些重复的代码之外,它还像冠军一样工作,同时允许下层客户端通过HTTP使用基于SOAP的端点.
查看MSDN 示例COM类,了解如何装饰将通过COM Interop公开的Facade类.它描述了您的类型需要暴露给COM感知客户端的神奇的属性.
基本概要是
您可能需要从自定义位置完全借阅阅读WCF配置中的提示,了解如何加载绑定和端点,如果您没有"拥有"主机,那么配置可能不在预期的mayapp.exe.config中.
不完全是你想要的答案,希望有这种经验的人会发帖.
ž
| 归档时间: |
|
| 查看次数: |
2004 次 |
| 最近记录: |