[英]Issues with COM DLL calling WCF Service
我有一个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,则第二种方法可以正常工作。 如果为true,则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为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);
}
问题:
首先...很抱歉您与COM打交道!
我们最近有机会使用C ++和VB6来使用4.0 WCF服务(通过httpBinding,尽管关系不大,具体取决于.NET的版本)。 我碰到了您可能做过的同一篇文章,并且坦率地讲, COM Moniker护罩适用于鸟类 。 使它以可靠的方式工作从未使我成功。 可能我只是一无所知。
不幸的是,那里有很多基于COM构建的“遗留”代码。
相反,我们非常成功地创建了带有实际WCF服务代理外观的.NET程序集。 我们通过.NET COM Interop公开了外观,然后将其委派给内部代理类,该类由“添加服务引用”向导生成。 除了少量重复的代码外,它还像冠军一样工作,同时允许低级客户端通过HTTP使用基于SOAP的端点。
请查看MSDN 示例COM类,以了解如何装饰将通过COM Interop公开的外观类。 它描述了您的类型需要向COM感知客户端公开的属性的神奇效果。
基本轮廓是
您可能需要完全借鉴“从自定义位置读取WCF配置”中有关如何加载绑定和终结点的技巧,如果您不“拥有”主机,则可能不在预期的mayapp.exe.config中。
并非您要找的答案,希望有这种经验的人可以发表。
ž
问题2的可能答案service:
在这种情况下,您的绰号缺少其方案前缀“ service:
”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.