UPDATE: Guardando attraverso il protocollo here, non riesco a capire cosa va inserito nel Record Envelope Unsized. Non riesco a trovare alcun esempio online.Come si chiama un metodo WCF da C++ usando pipe Named?
ORIGINALE:
Ho il seguente servizio WCF
static void Main(string[] args)
{
var inst = new PlusFiver();
using (ServiceHost host = new ServiceHost(inst,
new Uri[] { new Uri("net.pipe://localhost") }))
{
host.AddServiceEndpoint(typeof(IPlusFive), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "PipePlusFive");
host.Open();
Console.WriteLine("Service is Available. Press enter to exit.");
Console.ReadLine();
host.Close();
}
}
[ServiceContract]
public interface IPlusFive
{
[OperationContract]
int PlusFive(int value);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class PlusFiver : IPlusFive
{
public int PlusFive(int value)
{
Console.WriteLine("Adding 5 to " + value);
return value + 5;
}
}
ho uscita aggiungendo 5 linea quindi so se il server ha elaborato la richiesta o meno.
Ho un client .NET che ho usato per testarlo e tutto funziona come previsto.
Ora voglio creare un client C++ non gestito per questo.
Ho capito come ottenere il nome della pipa e scriverlo.
Ho scaricato il protocollo da here
Posso scrivere sul pipe ma non riesco a leggerlo. Ogni volta che provo a leggere da esso ottengo un errore ERROR_BROKEN_PIPE 109 (0x6D) The pipe has been ended.
. Se sostituisco la lettura con una scrittura, la scrittura ha successo, quindi non penso che la pipe sia chiusa, almeno non finché non provo a leggere.
Ecco come mi collego al tubo.
HANDLE OpenPipe(OLECHAR* bstrGuid)
{
wstring pipeName = L"\\\\.\\pipe\\";
wstring strGuid = bstrGuid;
pipeName.append(strGuid.substr(1,36));
wcout << "Pipe Name " << endl;
wcout << pipeName.c_str() << endl;
HANDLE hPipe = CreateFile(pipeName.c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if(hPipe == INVALID_HANDLE_VALUE)
{
wcout << "failed to create pipe" << endl;
system("pause");
return NULL;
}
return hPipe;
}
questo è come sto creando il primo messaggio che sto mandando
std::list<wchar_t> GetFirstMessage()
{
std::list<wchar_t> message;
message.push_back(0x00);// version record
message.push_back(0x01);// major version
message.push_back(0x00);// minor version
message.push_back(0x01);// mode record
message.push_back(0x01);// singleton-unsized mode
message.push_back(0x02);// via record
wstring url = L"net.pipe://localhost/PipePlusFive";
message.push_back(url.length());// via length
for(int x= 0;x<url.length();x++)
{
message.push_back(url[x]); // via
}
message.push_back(0x03);
message.push_back(0x08);
return message;
}
Ecco come sto scrivendo al file.
int WriteMessage(HANDLE hPipe, LPVOID message, int size)
{
DWORD bytesWritten;
BOOL bWrite = WriteFile(hPipe, &message, size, &bytesWritten, NULL);
wcout << "Bytes Written: " << bytesWritten << endl;
if(bWrite == false)
{
wcout << "fail"<<endl;
CloseHandle(hPipe);
system("pause");
return 1;
}
return 0;
}
list<wchar_t> full_message = GetFirstMessage();
int result = WriteMessage(hPipe, &full_message, full_message.size());
if (result == 1)
{ return 1;}
Ecco come sto scrivendo il messaggio di fine
wchar_t message = 12;
result = WriteMessage(hPipe, &message, 1);
if (result == 1)
{ return 1;}
Ecco come sto cercando di leggere la risposta
char buffer[10];
DWORD bytesRead;
BOOL bRead = ReadFile(hPipe, buffer, 1, &bytesRead, NULL);
if(bRead == false)
{
wcout << "fail read"<<endl;
wcout << "error: " << GetLastError() << endl;
CloseHandle(hPipe);
system("pause");
return 1;
}
Sono nuovo di C++, così Non so se non sto seguendo il protocollo correttamente o commettendo uno stupido errore nel modo in cui sto provando a farlo?
UPDATE: Il problema era che stavo scrivendo l'indirizzo del puntatore alla named pipe invece del contenuto della lista. L'ho risolto e ora sono in grado di leggere il Preamble Ack Record. Ora devo capire che cosa deve essere inviato per la parte successiva del protocollo.
Non è possibile utilizzare il C++ gestito o un altro legame WCF più semplice (REST, ecc.)? –
Non riesco a utilizzare il C++ gestito. Penso che il RESTO dovrebbe rallentare. – scott
Ecco una soluzione qui: http://stackoverflow.com/questions/686452/create-wcf-service-for-unmanaged-c-clients ma utilizza alcuni pezzi di C++ gestito –