2012-07-25 84 views
0

我想从非托管代码访问wcf服务。 该服务只是连接到字符串并返回它们,以保持简单。从非托管C++调用WCF服务导致访问冲突

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互操作注册并且也使用运行主机的服务引用。

[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:

“ unhendeled异常在0x75 ...在xyz.exe:Microsoft C++异常:_com_error在内存位置0x ...“

然后我可以继续并在strlen.asm中获取下一个异常:

“在xyz.exe在0x5d Unhandeled例外...(msvcr100d.dll):将0xC0 ...:访问冲突读取地址0x00 ......”

这个异常后停止。 也许有人有这个问题的解决方案或错误的想法。我只是使用这个例子来保持简单。我正在研究的项目使用相同的结构。它也使用wcf服务,这些将从非托管C++中调用。

+0

嗨,你能确认q不是NULL吗?所以CoCreateInstance返回有效的指针到请求的接口?我没有在代码中看到任何验证,所以这就是为什么我问。它不应该是__uuidof(IStringconcat_IAMCOM)吗? – Zilog 2012-07-25 09:54:34

+0

你是对的q是NULL,所以它不返回一个有效的指针。我试着用__uuidof(IStringconcat_IAMCOM),也返回一个空指针,好,所以我得到一个NULL指针异常。 – raf 2012-07-25 10:27:47

+0

尝试添加[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]到您的接口 – Zilog 2012-07-25 10:40:28

回答

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 
+0

感谢您的帮助,现在它可以工作。 – raf 2012-07-26 10:01:42

0

我在C++代码中发生错误,错误地调用了CoCreateInstance(...),感谢zilog的帮助。

IStringconcat_IAMCOM* q; 
hr = CoCreateInstance(__uuidof(Stringconcat_IAMCOM), NULL, CLSCTX_INPROC_SERVER, __uuidof(IStringconcat_IAMCOM), (void**)&q); 

而且在serviceproxy的调用中也出现错误。 我不得不添加到基地址的端点属性地址=“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的服务电话,那是伟大的!