Para aquellos que estén interesados, encontré una solución de servidor ATL semi-funcional. El siguiente es el código de host, observe que está utilizando BasicHttpBinding, que es la única que trabaja con servidor ATL:
código
var svc = new Service1();
Uri uri = new Uri("http://localhost:8200/Service1");
ServiceHost host = new ServiceHost(typeof(Service1), uri);
var binding = new BasicHttpBinding();
ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(IService1), binding, uri);
endpoint.Behaviors.Add(new InlineXsdInWsdlBehavior());
host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
var mex = host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.Open();
Console.ReadLine();
para InlineXsdInWsdlBehavior se pudo encontrar here. Es necesario realizar un cambio importante en InlineXsdInWsdlBehavior para que funcione correctamente con sproxy cuando se trate de tipos complejos. Es causado por el error en sproxy, que no abarca correctamente los alias del espacio de nombres, por lo que wsdl no puede tener alias de espacio de nombres repetidos o sproxy se va a destruir.He aquí las funciones que debe cambiar:
public void ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)
{
int tnsCount = 0;
XmlSchemaSet schemaSet = exporter.GeneratedXmlSchemas;
foreach (WsdlDescription wsdl in exporter.GeneratedWsdlDocuments)
{
//
// Recursively find all schemas imported by this wsdl
// and then add them. In the process, remove any
// <xsd:imports/>
//
List<XmlSchema> importsList = new List<XmlSchema>();
foreach (XmlSchema schema in wsdl.Types.Schemas)
{
AddImportedSchemas(schema, schemaSet, importsList, ref tnsCount);
}
wsdl.Types.Schemas.Clear();
foreach (XmlSchema schema in importsList)
{
RemoveXsdImports(schema);
wsdl.Types.Schemas.Add(schema);
}
}
}
private void AddImportedSchemas(XmlSchema schema, XmlSchemaSet schemaSet, List<XmlSchema> importsList, ref int tnsCount)
{
foreach (XmlSchemaImport import in schema.Includes)
{
ICollection realSchemas = schemaSet.Schemas(import.Namespace);
foreach (XmlSchema ixsd in realSchemas)
{
if (!importsList.Contains(ixsd))
{
var new_namespaces = new XmlSerializerNamespaces();
foreach (var ns in ixsd.Namespaces.ToArray())
{
var new_pfx = (ns.Name == "tns") ? string.Format("tns{0}", tnsCount++) : ns.Name;
new_namespaces.Add(new_pfx, ns.Namespace);
}
ixsd.Namespaces = new_namespaces;
importsList.Add(ixsd);
AddImportedSchemas(ixsd, schemaSet, importsList, ref tnsCount);
}
}
}
}
El siguiente paso es generar encabezado de C++:
sproxy.exe /wsdl http://localhost:8200/Service1?wsdl
y luego se programa en C++ es así:
using namespace Service1;
CoInitializeEx(NULL, COINIT_MULTITHREADED );
{
CService1T<CSoapWininetClient> cli;
cli.SetUrl(_T("http://localhost:8200/Service1"));
HRESULT hr = cli.HelloWorld(); //todo: analyze hr
}
CoUninitialize();
return 0;
resultante código C++ maneja complejo tipos bastante decentemente, excepto que no puede asignar NULL a los objetos.
Disculpa las molestias. He actualizado mi respuesta. Espero eso ayude. –
Puede modificar el servicio WCF para ofrecer extremos SOAP y REST, y luego usar el punto final REST de C++. (Siempre que sus tipos de datos sean fácilmente analizados en C++). Consulte: http://stackoverflow.com/questions/186631/rest-soap-endpoints-for-a-wcf-service –