2010-04-23 16 views
5

मैं सी ++ में लिखा गया इंजेक्शन। डीएल बना रहा हूं, और मैं नामित पाइप का उपयोग कर सी # ऐप के साथ संवाद करना चाहता हूं।नामित पाइप का उपयोग कर C++ .dll और C# ऐप के बीच संदेश कैसे भेजें?

अब, मैं सी # ऐप में System.IO.Pipe .NET कक्षाओं में निर्मित का उपयोग कर रहा हूं, और मैं सी ++ में नियमित कार्यों का उपयोग कर रहा हूं।

मुझे सी ++ में बहुत अधिक अनुभव नहीं है (पढ़ें: यह मेरा पहला सी ++ कोड है ..), मुझे सी # में अनुभव है।

ऐसा लगता है कि सर्वर और क्लाइंट के साथ कनेक्शन काम कर रहा है, केवल समस्या यह है कि संदेश भेजा जा रहा है। मैंने .dll सर्वर को बनाने की कोशिश की, सी # ऐप सर्वर, पाइप दिशा InOut (डुप्लेक्स) बनाने लेकिन कोई भी काम करने लगता है।

DWORD ServerCreate() // function to create the server and wait till it successfully creates it to return. 
{ 
    hPipe = CreateNamedPipe(pipename,//The unique pipe name. This string must have the following form: \\.\pipe\pipename 
    PIPE_ACCESS_DUPLEX, 
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT, //write and read and return right away 
    PIPE_UNLIMITED_INSTANCES,//The maximum number of instances that can be created for this pipe 
    4096 , // output time-out 
    4096 , // input time-out 
    0,//client time-out 
    NULL); 

    if(hPipe== INVALID_HANDLE_VALUE) 
    { 
    return 1;//failed 
    } 
    else 
    return 0;//success 
} 

void SendMsg(string msg) 
{ 
    DWORD cbWritten; 
    WriteFile(hPipe,msg.c_str(), msg.length()+1, &cbWritten,NULL); 
} 

void ProccesingPipeInstance() 
{ 
    while(ServerCreate() == 1)//if failed 
{ 
    Sleep(1000);  
} 

//if created success, wait to connect 
ConnectNamedPipe(hPipe, NULL); 
for(;;) 
{ 
    SendMsg("HI!"); 
    if(ConnectNamedPipe(hPipe, NULL)==0) 
     if(GetLastError()==ERROR_NO_DATA) 
     { 
      DebugPrintA("previous closed,ERROR_NO_DATA"); 
      DisconnectNamedPipe(hPipe); 
      ConnectNamedPipe(hPipe, NULL); 
     } 
    Sleep(1000); 

} 

और इस तरह सी # cliend:

static void Main(string[] args) 
    { 
     Console.WriteLine("Hello!"); 

     using (var pipe = new NamedPipeClientStream(".", "HyprPipe", PipeDirection.In)) 
     { 
      Console.WriteLine("Created Client!"); 

      Console.Write("Connecting to pipe server in the .dll ..."); 
      pipe.Connect(); 

      Console.WriteLine("DONE!"); 

      using (var pr = new StreamReader(pipe)) 
      { 
       string t; 
       while ((t = pr.ReadLine()) != null) 
       { 
        Console.WriteLine("Message: {0}",t); 
       } 
      } 
     } 
    } 

जब मैं .dll सर्वर है, जो सी # अनुप्रयोग के लिए संदेश भेजता करने की कोशिश की, कोड मैं का इस्तेमाल किया इस तरह था

मुझे लगता है कि सी # क्लाइंट .dll से जुड़ा हुआ है, लेकिन इसे कोई संदेश नहीं मिलेगा .. मैंने इसे दूसरी तरफ करने की कोशिश की, जैसा कि मैंने पहले कहा था, और सी # को संदेश भेजने की कोशिश कर रहा था। डीएलएल, जो उन्हें एक संदेश बॉक्स में दिखाएगा। .dll को इंजेक्शन दिया गया था और सी # सर्वर से कनेक्ट किया गया था, लेकिन जब इसे एक संदेश प्राप्त हुआ तो उसने उस एप्लिकेशन को क्रैश कर दिया जिस पर इसे इंजेक्शन दिया गया था।

कृपया मेरी मदद करो, या कैसे सी ++ और सी # अनुप्रयोग

उत्तर

15

कुछ बातें बीच नामित पाइप का उपयोग करने पर मेरे गाइड।

1- आप एक ही पाइप नाम
सी ++ का उपयोग कर रहे: "। \\ \ पाइप \ HyperPipe"
सी #: "HyperPipe"

2- मैं सी # पक्ष यह हो सकता है पर लगता है ReadToEnd() का उपयोग करने के लिए बेहतर हो, मैंने केवल सी ++ में नामित पाइप का उपयोग किया है, लेकिन मुझे लगता है कि ReadToEnd() एक संदेश पढ़ेगा क्योंकि आप संदेश आधारित पाइप का उपयोग कर रहे हैं।

3- सी ++ पक्ष पर, आप गैर-अवरुद्ध पाइप का उपयोग करने और कनेक्शन और डेटा आदि के लिए पाइप मतदान करने की कोशिश कर रहे हैं। मैं तीन चीजों में से एक का सुझाव दूंगा।

 
    a - Use a blocking pipe on a separate thread or 
    b - Use non blocking pipes using Overlapped IO 
    c - Use non blocking pipes using IOCompletion ports 

पहला विकल्प आसान हो सकता है और के लिए यह क्या लगता है आप की तरह कर रहे हैं, यह ठीक स्केल करेगा। यहां एक सरल नमूना का लिंक है (ए) http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspx

4- सुनिश्चित करें कि आपके एन्कोडिंग दोनों तरफ से मेल खाते हैं। उदाहरण के लिए, यदि आपका सी ++ कोड यूनिकोड के लिए संकलित किया गया है, तो आपको यूनिकोड एन्कोडिंग का उपयोग करके सी # पक्ष पर पाइप स्ट्रीम को पढ़ना होगा। कुछ की तरह कुछ चीज।

using (StreamReader rdr = new StreamReader(pipe, System.Text.Encoding.Unicode)) 
{ 
    System.Console.WriteLine(rdr.ReadToEnd()); 
} 

अद्यतन: जब से मैं सी # में इस के साथ काम नहीं किया था मैंने सोचा कि मैं एक छोटे से परीक्षण लिखेंगे। अवरुद्ध पाइप का उपयोग करके कोई थ्रेडिंग या कुछ भी नहीं, बस मूलभूत कार्य की पुष्टि करने के लिए, यहां बहुत मोटा परीक्षण कोड है।

सी ++ सर्वर

#include <tchar.h> 
#include <windows.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HANDLE hPipe = ::CreateNamedPipe(_T("\\\\.\\pipe\\HyperPipe"), 
    PIPE_ACCESS_DUPLEX, 
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 
    PIPE_UNLIMITED_INSTANCES, 
    4096, 
    4096, 
    0, 
    NULL); 


    ConnectNamedPipe(hPipe, NULL); 

    LPTSTR data = _T("Hello"); 
    DWORD bytesWritten = 0; 
    WriteFile(hPipe, data, _tcslen(data) * sizeof(TCHAR), &bytesWritten, NULL); 
    CloseHandle(hPipe); 
    return 0; 
} 

सी # क्लाइंट

using System; 
using System.Text; 
using System.IO; 
using System.IO.Pipes; 

namespace CSPipe 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     NamedPipeClientStream pipe = new NamedPipeClientStream(".", "HyperPipe", PipeDirection.InOut); 
     pipe.Connect(); 
     using (StreamReader rdr = new StreamReader(pipe, Encoding.Unicode)) 
     { 
     System.Console.WriteLine(rdr.ReadToEnd()); 
     } 

     Console.ReadKey(); 
    } 
    } 
} 
+0

ओह यार, आप बोल्ड में C++ pipenames के बीच मतभेद और ग # रखना चाहिए। जब तक मुझे आपका जवाब नहीं मिला तब तक मैंने HOURS समस्या निवारण को बर्बाद कर दिया। –

+0

@BrianFairservice - हो गया :)। मुझे खुशी है कि इस पोस्ट ने मदद की! –

संबंधित मुद्दे