2012-07-25 83 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的服務電話,那是偉大的!