스키마 지원
WsUtil.exe는 XML 스키마에 지정된 XSD 스키마를 지원합니다. xsd 파일 및 wsdl:type은 전역 요소가 매개 변수 목록이 될 수 있는 경우 wsdl:type에서 예외를 제외하고 동일한 범주에서 처리되어야 합니다. Wsutil.exe는 serializer에서 사용할 수 있는 모든 전역 요소 정의에 대한 요소 설명을 생성하고 WSDL 지원에 지정된 매개 변수 구조에 대한 추가 출력을 생성합니다.
WsUtil.exe는 XSD 스키마의 전체 범위를 지원하지 않습니다. 현재 지원 수준은 스키마 지원 수준에서 정의 됩니다.
식별자 생성
스키마의 요소 이름 또는 형식 이름이 유효한 C 식별자가 아닐 수 있으며 이름은 생성된 유효한 C 이름으로 정규화됩니다. 잘못된 C 식별자 문자가 16진수 이름으로 변환되고 필요한 경우 이름 앞에 밑줄 '_'이 추가될 수 있습니다. 익명 형식은 바깥쪽 요소 이름의 이름을 따서 명명되지만 이름 충돌을 방지하기 위해 밑줄 "_"을 접두사로 묶습니다. 전역 형식 이름은 잘못된 문자가 정규화된 후 그대로 유지됩니다. 중첩된 무명 형식에는 부모 형식 이름이 접두사로 지정됩니다.
모든 전역 요소 정의에 대해 wsutil.exe는 전역 설명 구조에서 WS_ELEMENT_DESCRIPTION 생성합니다. 모든 전역 형식 정의에 대해 wsutil.exe는 애플리케이션에서 참조할 전역 설명 구조에 형식 설명을 생성합니다.
구조체의 각 필드에 대해 wsutil.exe는 엔클로저 구조의 일부로 포함된 WS_FIELD_DESCRIPTION 생성합니다.
WS_VALUE_TYPE 나열된 값 형식은 단순 형식으로 처리됩니다. WS_VALUE_TYPE 실제로 WS_TYPE 하위 집합입니다. 여기에는 DECIMAL, WS_DATETIME 및 UUID뿐만 아니라 기본 정수 및 부동 소수점 데이터 형식도 포함됩니다.
서비스 모델에서 단순 형식은 값으로 전달되고 out 및 in,out 단순 형식은 참조로 전달됩니다.
Wsutil은 단순 형식을 포함하는 전역 요소에 대해 아래와 같은 간단한 요소 설명을 만듭니다.
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="helloworld" type="xs:int"></xs:element>
</xs:schema>
Wsutil은 아래 요소 설명을 생성합니다.
... // global elements
{ // helloworld
{
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.helloworldTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.helloworldTypeNamespace,
WS_INT32_TYPE,
0,
},
}, // helloworld
...
이 구조체는 헤더 파일에 생성된 전역 설명 구조의 일부로 생성됩니다.
typedef struct _example_wsdl
{
WS_ELEMENT_DESCRIPTION helloworld;
} _example_wsdl;
maxOccurs가 1보다 크거나 항목이 하나만 있는 시퀀스가 있고 자식 요소의 maxOccurs가 1보다 큰 요소는 배열로 처리됩니다. 스키마의 배열 요소에 대해 wsutil.exe는 유선으로 이동하지 않는 개수 필드와 배열 형식을 포함하는 포인터 필드의 두 필드를 생성합니다.
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SimpleArray">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="50" name="a" nillable="true" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
헤더 파일에는 배열의 개수를 지정하는 aCount 필드와 함께 배열에 대한 C 구조 정의가 포함됩니다.
typedef struct SimpleArray
{
unsigned int aCount ;
int * a;
} SimpleArray;
다음은 배열을 설명하는 LocalDefinition 프로토타입의 일부입니다.
... // globalElement part of the LocalDefinitions.
struct // SimpleArray
{
struct // SimpleArray
{
WS_FIELD_DESCRIPTION a;
WS_FIELD_DESCRIPTION * SimpleArrayFields [1];
WS_STRUCT_DESCRIPTION structDesc;
} SimpleArraydescs; // SimpleArray
WS_ELEMENT_DESCRIPTION elementDesc;
} SimpleArray;
// Method with array parameters.
typedef HRESULT (CALLBACK *SimpleMethodCallback)(
const WS_OPERATION_CONTEXT* context,
unsigned int aCount,
int* a,
unsigned int *bCount,
int** b,
unsigned int* cCount,
int** c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
HRESULT CALLBACK SimpleMethod (
WS_SERVICE_PROXY* serviceProxy,
WS_HEAP* heap,
unsigned int aCount,
int* a,
unsigned int *bCount,
int** b,
unsigned int* cCount,
int** c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
다음은 위의 설명에 대한 생성된 정의입니다. 필드를 배열 필드로 나타내는 WS_REPEATING_ELEMENT_FIELD_MAPPING 확인합니다.
...
{ // SimpleArray
{ // SimpleArray
{ // field description for a
WS_REPEATING_ELEMENT_FIELD_MAPPING,
0,
0,
WS_INT32_TYPE,
0,
WsOffsetOf(SimpleArray, a),
0,
0,
WsOffsetOf(SimpleArray, aCount),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
}, // end of field description for a
{ // fields description for SimpleArray
(WS_FIELD_DESCRIPTION*)&example_wsdlLocalDefinitions.globalElements.SimpleArray.SimpleArraydescs.a,
},
{
sizeof(SimpleArray),
__alignof(SimpleArray),
(WS_FIELD_DESCRIPTION**)example_wsdlLocalDefinitions.globalElements.SimpleArray.SimpleArraydescs.
SimpleArrayFields,
WsCountOf(example_wsdlLocalDefinitions.globalElements.SimpleArray.SimpleArraydescs.SimpleArrayFields),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
}, // struct description for SimpleArray
}, // SimpleArray
{
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_STRUCT_TYPE,
(void *)&example_wsdlLocalDefinitions.globalElements.SimpleArray.SimpleArraydescs.structDesc,
},
}, // SimpleArray
...
배열이 입력/출력 메시지의 매개 변수 필드인 경우 메서드에 대해 두 개의 실제 매개 변수가 생성됩니다. 배열이 out 또는 in,out 매개 변수인 경우 paramStruct의 두 필드에 대해 하나의 추가 간접 참조 수준이 있습니다.
배열에 maxOccur="unbounded"를 지정하지 않는 것이 좋습니다. 대신 고정 정수 수를 지정하여 허용되는 배열 수의 상한을 설정해야 합니다. 범위는 정수 형식뿐만 아니라 문자열, 바이트 배열 및 제네릭 배열에도 지원됩니다.
경우에 따라 배열이 최상위 구조체에 포함되도록 다른 구조 안에 래핑됩니다. 이 경우 중간 래퍼 계층을 제거해야 합니다. WsUtil.exe는 위에서 설명한 SimpleArray와 동일한 프로토타입 및 설명을 생성합니다.
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="SimpleArray">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="50" name="aa" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:element name="SimpleArrayWrapper">
<xs:complexType>
<xs:sequence>
<xs:element name="SimpleArray" type="tns:SimpleArray" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Wsutil은 SimpleArrayWrapper가 SimpleArray의 래퍼임을 감지하고 SimpleArray에 대한 별도의 구조로 다음 구조만 생성합니다.
typedef struct SimpleArrayWrapper
{
unsigned int SimpleArrayCount ;
int * SimpleArray;
} SimpleArrayWrapper;
.. // global element inside the LocalDefinitions prototype
struct // SimpleArrayWrapper
{
struct // SimpleArrayWrapper
{
WS_FIELD_DESCRIPTION SimpleArray;
WS_FIELD_DESCRIPTION * SimpleArrayWrapperFields [1];
WS_STRUCT_DESCRIPTION structDesc;
} SimpleArrayWrapperdescs; // SimpleArrayWrapper
WS_ELEMENT_DESCRIPTION elementDesc;
} SimpleArrayWrapper;
...
wsutil.exe는 위의 일치하는 프로토타입에 대해 다음 정의를 생성합니다. 필드 설명에서 래퍼 이름 및 래퍼 네임스페이스 필드가 채워집니다.
... // global element part of the LocalDefinitions structure:
{ // SimpleArrayWrapper
{ // SimpleArrayWrapper
{ // WS_FIELD_DESCRIPTION for SimpleArray
WS_REPEATING_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayWrapperName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayNamespace,
WS_INT32_TYPE,
0,
WsOffsetOf(SimpleArrayWrapper, SimpleArray),
0,
0,
WsOffsetOf(SimpleArrayWrapper, SimpleArrayCount),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayNamespace,
}, // end of field description for SimpleArray
{ // array of field descriptions for SimpleArrayWrapper
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.SimpleArrayWrapper.SimpleArrayWrapperdescs.SimpleArray,
},
{ // WS_STRUCT_DESCRIPTION for SimpleArrayWrapper
sizeof(SimpleArrayWrapper),
__alignof(SimpleArrayWrapper),
(WS_FIELD_DESCRIPTION**)example_wsdlLocalDefinitions.globalElements.SimpleArrayWrapper.SimpleArrayWrapperdescs.SimpleArrayWrapperFields,
WsCountOf(example_wsdlLocalDefinitions.globalElements.SimpleArrayWrapper.SimpleArrayWrapperdescs.SimpleArrayWrapperFields),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayWrapperTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayNamespace,
}, // struct description for SimpleArrayWrapper
}, // SimpleArrayWrapper
{ // WS_ELEMENT_DESCRIPTION for SimpleArrayWrapper
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayWrapperTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.SimpleArrayNamespace,
WS_STRUCT_TYPE,
(void *)&example_wsdlLocalDefinitions.globalElements.SimpleArrayWrapper.SimpleArrayWrapperdescs.structDesc,
},
}, // SimpleArrayWrapper
시퀀스에 여러 요소가 있는 complexType은 구조체입니다. 예를 들면 다음과 같습니다.
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="StructType">
<xs:sequence>
<xs:element minOccurs="0" name="FirstName" nillable="true" type="xs:string" />
<xs:element minOccurs="0" name="LastName" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="StructType" nillable="true" type="tns:StructType" />
</xs:schema>
Wsutil.exe는 다음과 같이 구조 프로토타입을 생성합니다.
struct StructType
{
WS_STRING FirstName;
WS_STRING LastName;
};
// methods using structure parameters.
typedef HRESULT (CALLBACK *SimpleMethodCallback) (
const WS_OPERATION_CONTEXT* context,
StructType* a,
StructType** b,
StructType** c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
HRESULT CALLBACK SimpleMethod (WS_SERVICE_PROXY* serviceProxy,
WS_HEAP* heap,
StructType* a,
StructType** b,
StructType** c,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
wsutil은 LocalDefinition에 대해 다음 프로토타입을 생성합니다.
struct // StructType
{
struct // StructType
{
WS_FIELD_DESCRIPTION FirstName;
WS_FIELD_DESCRIPTION LastName;
WS_FIELD_DESCRIPTION * StructTypeFields [2];
WS_STRUCT_DESCRIPTION structDesc;
} StructTypedescs; // StructType
WS_ELEMENT_DESCRIPTION elementDesc;
}
구조체에 대한 정의는 구조체에 두 개의 필드 설명이 있는 아래와 같습니다.
// global element inside LocalDefinitions.
{ // StructType
{ // StructType
{ // field description for FirstName
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.FirstNameLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.FirstNameNamespace,
WS_STRING_TYPE,
0,
WsOffsetOf(StructType, FirstName),
0,
0,
}, // end of field description for FirstName
{ // field description for LastName
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.LastNameLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.FirstNameNamespace,
WS_STRING_TYPE,
0,
WsOffsetOf(StructType, LastName),
0,
0,
}, // end of field description for LastName
{ // fields description for StructType
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.StructType.StructTypedescs.FirstName,
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.StructType.StructTypedescs.LastName,
},
{ // WS_STRUCT_DESCRIPTION for StructType
sizeof(StructType),
__alignof(StructType),
(WS_FIELD_DESCRIPTION**)example_wsdlLocalDefinitions.globalElements.StructType.StructTypedescs.StructTypeFields,
WsCountOf(example_wsdlLocalDefinitions.globalElements.StructType.StructTypedescs.StructTypeFields),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.StructTypeTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.FirstNameNamespace,
}, // struct description for StructType
}, // StructType
{
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.StructTypeTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.FirstNameNamespace,
WS_STRUCT_TYPE,
(void *)&example_wsdlLocalDefinitions.globalElements.StructType.StructTypedescs.structDesc,
},
}, // StructType
확장성을 지원하기 위해 포함된 구조체는 항상 참조로 전달됩니다. 서비스에서 모든 out 또는 in,out 구조체는 구조체의 향후 확장을 허용하고 nillable 구조를 허용하기 위해 이중 포인터로 전달됩니다.
재귀 구조가 지원되며 포함된 형식은 참조로 전달됩니다. 다음 wsdl의 경우:
<xs:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SimpleMethod">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="a" type="xs:int" />
<xs:element minOccurs="0" name="b" type="tns:example" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="example">
<xs:sequence>
<xs:element minOccurs="0" name="d" type="tns:example" />
<xs:element minOccurs="0" name="c" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Wsutil은 다음과 같은 형식 정의와 형식 설명을 생성합니다.
typedef struct example
{
struct example * d;
int32 c;
} example;
typedef struct SimpleMethod
{
unsigned __int32 a;
struct example * b;
} SimpleMethod;
// global element part of the LocalDefinitions.
...
struct // SimpleMethod
{
struct // SimpleMethod
{
WS_FIELD_DESCRIPTION a;
struct // example
{
WS_FIELD_DESCRIPTION d;
WS_FIELD_DESCRIPTION c;
WS_FIELD_DESCRIPTION * exampleFields [2];
WS_STRUCT_DESCRIPTION structDesc;
} exampledescs; // example
WS_FIELD_DESCRIPTION b;
WS_FIELD_DESCRIPTION * SimpleMethodFields [2];
WS_STRUCT_DESCRIPTION structDesc;
} SimpleMethoddescs; // SimpleMethod
WS_ELEMENT_DESCRIPTION elementDesc;
} SimpleMethod;
...
정의는 다음과 같이 생성됩니다.
{ // SimpleMethod
{ // field description for a
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_INT32_TYPE,
0,
WsOffsetOf(SimpleMethod, a),
0,
0,
}, // end of field description for a
{ // example
{ // field description for d
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.dLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_STRUCT_TYPE,
(WS_STRUCT_DESCRIPTION*)&example_wsdlLocalDefinitions.globalElements.SimpleMethod.SimpleMethoddescs.structDesc,
WsOffsetOf(example, d),
WS_FIELD_POINTER,
0,
}, // end of field description for d
{ // field description for c
WS_ELEMENT_FIELD_MAPPING,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.cLocalName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
WS_INT32_TYPE,
0,
WsOffsetOf(example, c),
0,
0,
}, // end of field description for c
{ // fields description for example
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.SimpleMethod.SimpleMethoddescs.exampledescs.d,
(WS_FIELD_DESCRIPTION *)&example_wsdlLocalDefinitions.globalElements.SimpleMethod.SimpleMethoddescs.exampledescs.c,
},
{
sizeof(example),
__alignof(example),
(WS_FIELD_DESCRIPTION**)example_wsdlLocalDefinitions.globalElements.SimpleMethod.SimpleMethoddescs.exampledescs.exampleFields,
WsCountOf(example_wsdlLocalDefinitions.globalElements.SimpleMethod.SimpleMethoddescs.exampledescs.exampleFields),
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.exampleTypeName,
(WS_XML_STRING*)&example_wsdlLocalDefinitions.dictionary.xmlStrings.aNamespace,
}, // struct description for example
}
wsutil은 한 복합 형식이 다른 복합 형식에 대한 확장인 복합 형식 확장을 지원합니다.
<s:schema xmlns:tns="http://Example.org" elementFormDefault="qualified"
targetNamespace="http://Example.org" xmlns:s="http://www.w3.org/2001/XMLSchema">
<s:complexType name="LinkList">
<s:sequence>
<s:element minOccurs="0" name="d" type="tns:LinkList" />
<s:element minOccurs="0" name="c" type="s:int" />
</s:sequence>
</s:complexType>
<s:element name="DerivedLinkList">
<s:complexType>
<s:complexContent>
<s:extension base="tns:LinkList">
<s:sequence>
<s:element name="derive1" type="s:int" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
</s:element>
</s:schema>
위의 xsd 조각은 DerivedLinkList가 LinkList에서 파생됨을 나타냅니다.
Wsutil.exe는 애플리케이션이 기본 형식 및 파생 형식의 형식 정보를 보다 쉽게 설정할 수 있도록 C 및 C++ 모두에 대한 도우미 루틴을 생성합니다. 다음 코드에서 _WS_CPLUSPLUS 매크로는 C 및 C++ 언어에 대한 정의를 구분하는 데 사용됩니다.
#if defined(_WS_CPLUSPLUS)
typedef struct LinkList
{
LinkList();
LinkList(WS_STRUCT_DESCRIPTION*);
struct _DerivedLinkList* WINAPI As_DerivedLinkList();
const struct _WS_STRUCT_DESCRIPTION* _type;
struct LinkList * d;
int c;
} LinkList;
#endif
#if !defined(_WS_CPLUSPLUS)
typedef struct LinkList
{
const struct _WS_STRUCT_DESCRIPTION* _type;
struct LinkList * d;
int c;
} LinkList;
void WINAPI LinkList_Init(LinkList*);
#endif
#if defined(_WS_CPLUSPLUS)
typedef struct _DerivedLinkList:LinkList
{
_DerivedLinkList();
int derive1;
} _DerivedLinkList;
#endif
#if !defined(_WS_CPLUSPLUS)
typedef struct _DerivedLinkList
{
struct LinkList _base;
int derive1;
} _DerivedLinkList;
struct _DerivedLinkList* WINAPI LinkList_As_DerivedLinkList(LinkList*);
#endif
C 스타일 도우미에서 serialiation 전에 애플리케이션은 wsutil 생성 루틴 LinkList_Init 호출하여 구조를 초기화하고 형식 설명을 LinkList 형식 설명으로 설정합니다. 역직렬화 후 애플리케이션은 LinkList_As_DerivedLinkList 호출하여 파생 형식을 가져올 수 있습니다.
런타임에 형식 정보를 검색하기 위해 wsutil은 WS_STRUCT_DESCRIPTION* 형식 및 WS_TYPE_ATTRIBUTE_FIELD_MAPPING 필드 매핑을 사용하여 xsi:type 정보를 설명하는 기본 형식의 첫 번째 필드를 생성합니다. 애플리케이션은 필드를 직접 설정하거나 검사 실제 구조 유형을 결정할 수 있습니다. 예를 들어 다음 코드는 구조체의 형식을 DrivedLinkList로 설정합니다.
_DerivedLinkList derivedLinkList;
derivedLinkList._base._type = (WS_STRUCT_DESCRIPTION*)test_xsd.globalElements.DerivedLinkList.typeDescription;
WsWriteType(
writer,
WS_ELEMENT_TYPE_MAPPING,
WS_STRUCT_TYPE,
(WS_STRUCT_DESCRIPTION*)test_xsd.globalElements.DerivedLinkList.typeDescription,
...);
구조체가 역직렬화된 후 애플리케이션은 형식 설명을 직접 비교하여 역직렬화된 형식을 결정할 수 있습니다.
if (derviedLinkList._base._type == (WS_STRUCT_DESCRIPTION*)test_xsd.globalElements.DerivedLinkList.typeDescription)
{
// the deserialized type is of type _DerivedLinkList
...
}
wsutil은 기본 구조체와 파생 구조체 모두에 대한 클래스를 생성합니다. 기본 생성자는 형식 및 일치하는 형식 설명을 초기화합니다. AsDerivedType 루틴은 형식 간에 안전한 형식 캐스팅을 수행하는 데 도움이 됩니다.
{ // field description for typeOfLinkList
WS_TYPE_ATTRIBUTE_FIELD_MAPPING,
0,
0,
WS_DESCRIPTION_TYPE,
0,
WsOffsetOf(LinkList, typeOfLinkList),
0,
0,
}, // end of field description for typeOfLinkList ...
{
sizeof(LinkList),
__alignof(LinkList),
(WS_FIELD_DESCRIPTION**)&test_xsdLocalDefinitions.globalTypes.LinkListdescs.LinkListFields,
WsCountOf(test_xsdLocalDefinitions.globalTypes.LinkListdescs.LinkListFields),
(WS_XML_STRING*)&test_xsdLocalDefinitions.dictionary.xmlStrings.LinkListTypeName,
(WS_XML_STRING*)&test_xsdLocalDefinitions.dictionary.xmlStrings.LinkListTypeNamespace,
0,
(WS_STRUCT_DESCRIPTION**)&test_xsdLocalDefinitions.globalTypes.LinkListdescs.SubTypes,
1,
}, // struct description for LinkList
nillable 특성은 문자열, 구조체 및 바이트 배열에 대해 지원됩니다. WS_FIELD_NILLABLE 특성은 nillable 특성이 있는 필드에 추가됩니다. 요소가 nillable이면 포인터가 NULL로 설정됩니다. 구조체의 nillable 필드는 포인터로 처리됩니다. nillable 특성이 있는 매개 변수 구조는 참조로 전달됩니다.
값 형식은 출력 매개 변수에 대한 값 또는 참조로 전달되어야 합니다. 구조체만 제외하면 이중 포인터는 허용되지 않습니다.
메시지 파트의 "매개 변수" 이름에 대한 이전 설명을 기억하세요. 이 값을 지정하면 결과 서비스 작업에 대한 입력 및 출력 메시지에 대한 결합된 프레임을 생성하려고 합니다. 이 작업을 지정하지 않으면 결과 서비스 작업에는 입력 및 출력 메시지가 매개 변수로 구조체로 포함됩니다.
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://Sapphire.org"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing"
xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" targetNamespace="http://Sapphire.org"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:message name="ISimpleService_SimpleMethod_InputMessage">
<wsdl:part name="noparameters" element="tns:SimpleMethod" />
</wsdl:message>
<wsdl:message name="ISimpleService_SimpleMethod_OutputMessage">
<wsdl:part name="noparameters" element="tns:SimpleMethodResponse" />
</wsdl:message>
</wsdl:definitions>
따라서 SimpleMethod 작업의 경우 서비스 및 클라이언트에 대한 서명은 다음과 같습니다.
typedef HRESULT (CALLBACK *SimpleMethodCallback)
(const WS_OPERATION_CONTEXT* context,
SimpleMethodRequest* inMessage,
SimpleMethodResponse** outMessage,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
HRESULT CALLBACK SimpleMethod (
WS_SERVICE_PROXY* serviceProxy,
WS_HEAP* heap,
SimpleMethodRequest* inMessage,
SimpleMethodResponse** outMessage,
const WS_ASYNC_CONTEXT* asyncContext,
WS_ERROR* error);
Serialization뿐만 아니라 Wsutil 컴파일러 도구의 보안 섹션을 참조하세요.