我想从非托管代码访问wcf-service。 该服务只是串联到字符串并返回它们,以保持简单。
public class Stringconcat : IStringconcat
{
public string stringconcat(string a, string b)
{
return b + a;
}
}
[ServiceContract]
public interface IStringconcat
{
[OperationContract]
string stringconcat(string a, string b);
}
我使用引用该服务的.dll的c#控制台应用程序来托管该服务。 并公开服务的端点。 在Main()中:
using (ServiceHost host = new ServiceHost(typeof(stringconcatservice.Stringconcat)))
{
host.Open();
Console.WriteLine("Press <ENTER> to terminate the host application");
Console.ReadLine();
}
主机的配置如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior"
name="stringconcatservice.Stringconcat" >
<endpoint address="stringconcat" binding="basicHttpBinding"
name="basicHttp" contract="stringconcatservice.IStringconcat" />
<endpoint binding="mexHttpBinding" name="mex"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/stringconcatService" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
如果我从一个用于服务引用的基本地址的.net客户端调用该服务,现在一切正常。
StringconcatClient proxy = new StringconcatClient();
string a = " string a ";
string b = " string b ";
string c = proxy.stringconcat(a, b);
Console.WriteLine(c);
Console.WriteLine("Press <ENTER> to terminate Client.");
Console.ReadKey();
现在我遇到的问题。 因为我想从非托管c ++代码访问该服务。 为此我使用.dll注册com interop并使用正在运行的主机的服务引用。
[Guid("E4435D3B-CBC3-4D41-B4A5-D8116B394195")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Stringconcat_IAMCOM : IStringconcat_IAMCOM
{
public string stringconcat(string a, string b)
{
StringconcatClient client = new StringconcatClient();
return client.stringconcat(a, b);
}
}
[Guid("E130F97E-1844-4C8B-9E57-AF42632A2557")]
[ComVisible(true)]
public interface IStringconcat_IAMCOM
{
[DispId(1)]
string stringconcat(string a, string b);
}
现在,当我尝试通过中间件.dll访问服务时,使用c ++ ...
#import "..\stringconcatInteropSvcClient\bin\Debug\stringconcatInteropSvcClient.tlb"
#include <iostream>
#include <stdio.h>
using namespace stringconcatInteropSvcClient;
int main(int argc, const char* argv[])
{
HRESULT hr = CoInitialize(NULL);
BSTR a = L" string a ";
BSTR b = L" string b ";
IStringconcat_IAMCOM* q;
hr = CoCreateInstance(__uuidof(Stringconcat_IAMCOM), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IStringconcat_IAMCOM), (void**)&q );
std::cout << q->stringconcat(a, b);
//Uninitialize COM.
CoUninitialize();
return 0;
}
...我在stringconcatinteropsvcclient.tli中得到一个例外:
“x75z.exe中的0x75错误的非常规异常:Microsoft C ++异常:内存位置0x的_com_error ...”
然后我可以继续并在strlen.asm中获取下一个异常:
“xyz.exe中的0x5d ...(msvcr100d.dll)中的未触发异常:0xC0 ...:访问冲突读取位置0x00 ......”
此异常停止后。 也许有人有这个问题的解决方案或错误可能的想法。我只是用这个例子来保持简单。我正在研究的项目使用相同的结构。它还使用wcf服务,这些服务将从非托管c ++中调用。
答案 0 :(得分:1)
刚刚创建了一个小型测试项目,它正在运行:
namespace ComTest
{
[Guid("E4435D3B-CBC3-4D41-B4A5-D8116B394195")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Stringconcat_IAMCOM : IStringconcat_IAMCOM
{
public string stringconcat(string a, string b)
{
return a + b;
}
}
[Guid("E130F97E-1844-4C8B-9E57-AF42632A2557")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IStringconcat_IAMCOM
{
[DispId(1)]
string stringconcat(string a, string b);
}
}
客户:
#import "C:\Users\rst\Documents\Visual Studio 2008\Projects\ComTest\ComTest\bin\Debug\ComTest.tlb"
#include <iostream>
#include <stdio.h>
#include <windows.h>
using namespace ComTest;
int main(int argc, const char* argv[])
{
HRESULT hr = CoInitialize(NULL);
BSTR a = L" string a ";
BSTR b = L" string b ";
IStringconcat_IAMCOM* q;
hr = CoCreateInstance(__uuidof(Stringconcat_IAMCOM), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IStringconcat_IAMCOM), (void**)&q );
std::cout << q->stringconcat(a, b);
//Uninitialize COM.
CoUninitialize();
return 0;
}
我的程序集名称是ComTest.dll,所以我使用以下命令注册:
regasm Comtest.dll /CodeBase
答案 1 :(得分:0)
我在c ++代码中出错,CoCreateInstance(...)的错误调用,谢谢zilog的帮助。
IStringconcat_IAMCOM* q;
hr = CoCreateInstance(__uuidof(Stringconcat_IAMCOM), NULL, CLSCTX_INPROC_SERVER, __uuidof(IStringconcat_IAMCOM), (void**)&q );
对serviceproxy的调用也有错误。 我不得不在基地址中添加端点属性address =“stringconcat”。 地址应该是这样的:
http://localhost:8000/stringconcatService/stringconcat
我现在以这种方式创建服务代理:
[Guid("E4435D3B-CBC3-4D41-B4A5-D8116B394195")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class Stringconcat_IAMCOM : IStringconcat_IAMCOM
{
public string stringconcat(string a, string b)
{
EndpointAddress ep = new EndpointAddress("http://localhost:8000/stringconcatService/stringconcat");
proxy = ChannelFactory<IStringconcat>.CreateChannel(new BasicHttpBinding(), ep);
proxy.stringconcat(string a, string b);
}
}
[Guid("E130F97E-1844-4C8B-9E57-AF42632A2557")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IStringconcat_IAMCOM
{
[DispId(1)]
string stringconcat(string a, string b);
}
现在我可以从c ++到WCF-Services进行调用,非常棒!