compiling test.idl with dceidl - bit lairy and archaic

Luke Kenneth Casson Leighton lkcl at
Wed Jan 19 15:50:09 CST 2005

rob, hi,

okay, it was a bit hairy, but here's at least a first attempt, that
shows up the following.  it leads me to conclude that dce's idl compiler
was [is] a rather delayed work-in-progress that "DidTheJob(tm)" and then
microsoft decided "here we go, here we go, here we go..." and kinda
finished it off for a more "professional" developer market rather than
the "specialist" $USD 0.5billion market... kinda amusing really.

fyi and in case you're interested, i'm putting the
auto-generated test_cstub.cxx up at:

at 172k it's ... a _little_ excessive given that the idl file it came
from is only 750 lines long!


1) dceidl expects files to start with an interface definition
   and _then_ you can start putting structs and function definitions

2) dceidl doesn't appear to like you declaring structs without putting
   a typedef around them - even if you don't actually use the typedef.

3) dceidl is fussy about switch_type on nonencapsulated unions.

4) case statements where the switch variable is a char i
couldn't be bothered to find a way to let it be happy with case(1)
it was bitching about 1 not being a char so i converted to
a short and it stopped bitching.

5) range isn't implemented.  i don't imagine this will be difficult to
add: there are enough examples to work from in the code to add range.

6) explicit_handle doesn't appear to be understood (but i know
implicit_handle is because wez added that) so the Test2 interface
wouldn't compile.

7) there's a warning about floats - it seems that they get converted to
doubles "automatically" by non-Ansi c compilers and obviously the
DCE/RPC guys have seen this error _so_ many times they decided to add a
compiler warning about it...

8) __stdcall isn't supported (and i haven't a _bleedin'_ clue as to what
it is, neeeiiivah)

9) [ptr] _cannot_ be left out.

10) NonEncapsulated [out] Unions you _must_ return the switch statement
so i had to change to [in,out,ref] short *type ...

11) there's something weird about the stuff in ConformantPStruct
    that you created, rob, so i had to create typedef [ptr] long*
    pLong_t because a (long **) bitched about the long** not
    being a [ptr] even though the long* is.

    hey, don't ask me!

12) the other weird thing about ConformantPStruct was that ur..
    oh yes, a [ptr] *size wasn't acceptable as a size_is, so i 
    had to convert it to a [ref] and then that appeared to be okay:

		typedef [ref] long * pLong_tr;
		typedef struct ConformantPStruct {
			pLong_tr size;
			[size_is(*size)] char
		} TConformantPStruct;

13) i had to create a typedef FakeStringPtr which oh yes, that's right,
    this was the one where it was used as a FakeStringPtr ** and there
    wasn't a declaration about each of the *s being [ptr] i.e. * being
    [ptr] and ** being [ptr][ptr] so i got round that one by doing
	typedef [ptr] FakeString *FakeStringPtr ;
	void FullPointerIn2([in, ptr] FakeStringPtr * pFull);

14) there was some problem with the .acf file, possibly because a syntax
of several interfaces being defined in one .acf file is not supported
by the yacc syntax but several interfaces in one .idl file _is_

so i moved the Test2 and Test3 stuff into separate idl files.

15) i had a weird encounter with wchar_t so i substituted WCHAR which
exists in wez's wtypes.idl file and the problem went away.

16) wez's wtypes.idl already has a definition for LPWSTR so i commented
that out.

17) cpp_somethingorother("#define MAGIC_CHAR 0x54") isn't supported but
a pure and simple #define MAGIC_CHAR 0x54 is - so i went with that.

_other_ than that, it's all hunky-dory :)


so, your server-side code is testp.c, and the client-side code is

have to pay attention to lovely wife rather than boring computer so i'll
have a go at creating a Makefile cut/paste style from some examples i
know of in order to get a working client/server: will let you know how
it goes.


p.s. for convenience, i might convert RpcBindingFree etc. to
rpc_binding_free - hope you don't mind.

<a href=""></a>
-------------- next part --------------
#include "wtypes.idl"

interface Tests
	typedef struct _FakeString
		byte ch;
		byte ch2;
	} FakeString;

	typedef [ptr] FakeString *FakeStringPtr ;

	/* can't be bothered to look up how to do a case((char)1)
	   so am converting switch_type to short instead, and
	   all uses of it too
	typedef [switch_type(short)] union NonEncapsulated
		[case(1)] char ch;
		[case(2)] short s;
		[case(4)] long l;
		[case(5)] FakeString str;
	} NonEncapsulated;

	typedef union switch(short key)
		case 1: char ch;
		case 2: short s;
		case 4: long l;
		case 5: FakeString str;
	} Encapsulated;

	/* _not_ defined in /opt/dce/include/wtypes.idl: */
	/*typedef WCHAR WCHAR ; */

	/* already defined in the version of wtypes.idl 
	   in /opt/dce/include/wtypes.idl:
	   typedef [ptr, string] WCHAR * LPWSTR;*/

	#define MAGIC_CHAR 0x54
	#define MAGIC_SHORT 0x5784
	#define MAGIC_LONG 0x13578658
	#define MAGIC_DOUBLE 3.1415926535897932384626433832795
	#define MAGIC_CSTRING "Hello World!\n"

/* base types */
	void CharIn([in] char ch);
	void ByteIn([in] byte b);
	void SmallIn([in] small sm);
	void USmallIn([in] unsigned small sm);
	void WCharIn([in] WCHAR wch);
	void ShortIn([in] short sh);
	void UShortIn([in] unsigned short ush);
	void FloatIn([in] float f);
	void HyperIn([in] hyper h);
	void DoubleIn([in] double d);
	void ErrorStatusTIn([in] error_status_t err);
//	void Int3264([in] __int3264 i);
//	void UInt3264([in] unsigned __int3264 i);
/* pointers */
	void UniquePointerIn([in, unique] unsigned char *pUnique);
	void UniquePointerOut([in, out, unique] unsigned char *pUnique);
    void FullPointerIn([in, ptr] unsigned char * pFull);
    void FullPointerIn2([in, ptr] FakeStringPtr * pFull);
    void FullPointerOut([in, out, ptr] unsigned char * pFull);
/* misc */
    /* oops void RangedIn([in, range(0, 100)] unsigned long l); */
	char CharRet();
	short ShortRet();
	long LongRet();
	FakeString StructRet();
	float FloatRet();
	double DoubleRet();
	/* oops long __stdcall Stdcall([in] long l1, [in, out] long * pLong); */

/* arrays */
	void SmFixedArrayIn([in] unsigned char Array[10]);
	void SmFixedArrayOut([out] unsigned char Array[10]);
	void LgFixedArrayIn([in] unsigned char Array[65538]);
	void LgFixedArrayOut([out] unsigned char Array[65538]);
	void SmVaryingArrayIn([in] long size, [in, length_is(size)] unsigned char Array[10]);
	void SmVaryingArrayOut([in] long size, [out, length_is(size)] unsigned char Array[10]);
	void LgVaryingArrayIn([in] long size, [in, length_is(size)] unsigned char Array[65538]);
	void LgVaryingArrayOut([in] long size, [out, length_is(size)] unsigned char Array[65538]);
	void ConformantArrayIn([in] long size, [in, size_is(size)] unsigned char Array[]);
	void ConformantArrayOut([in] long size, [out, size_is(size)] unsigned char Array[]);
	void ConformantVaryingArrayIn([in] long size1, [in] long size2, [in, size_is(size1), length_is(size2)] unsigned char Array[]);
	void ConformantVaryingArrayOut([in] long size1, [in] long size2, [out, size_is(size1), length_is(size2)] unsigned char Array[]);
	void ComplexArrayIn([in] long size, [in, size_is(size)] char ComplexArray[][10]);

#if 0
	void DivTwoConformanceArrayIn([in] long size, [in, length_is(size/2)] unsigned char Array[10]);
	void MultTwoConformanceArrayIn([in] long size, [in, length_is(size*2)] unsigned char Array[10]);
	void AddOneConformanceArrayIn([in] long size, [in, length_is(size+1)] unsigned char Array[10]);
	void SubOneConformanceArrayIn([in] long size, [in, length_is(size-1)] unsigned char Array[10]);
	void CallbackConformanceArrayIn([in] long size, [in, length_is(size*2+1)] unsigned char Array[10]);

/* strings */
	void NonconformantString([in, string] char szString[10]);
	void ConformantString([in, string] char * pszString);
#if 1
	void NonconformantStructStr([in, string] FakeString szString[10]);
	void ConformantStructStr([in, string] FakeString * szString);
	void ConformantStructStrSized([in] unsigned long l, [in, string,size_is(l)] FakeString * pszString);
	void ConformantWideString([in, string] WCHAR * pszString);
/* structures */
	typedef [ptr] long * pLong_t;
	typedef [ref] long * pLong_tr;
	typedef struct PointerStruct {
		pLong_t pLong;
	} TPointerStruct;

	typedef struct ConformantStruct {
		long size; [size_is(size)] char array[];
	} TConformantStruct;

	typedef struct ConformantPStruct {
		pLong_tr size;
		[size_is(*size)] char array[];
	} TConformantPStruct;

	typedef struct ConformantVStruct { long len; [length_is(len)] char array[10]; } TConformantVStruct ;
	typedef struct HardStruct { short type; [switch_is(type)] union NonEncapsulated u; } THardStruct ;
	typedef struct ComplexStruct { long size; [size_is(size)] char ComplexArray[][10]; } TComplexStruct ;

	void SimpleStructIn([in] FakeString * s);
	void SimpleStructOut([out] FakeString * s);
	void SimplePointerStructIn([in] struct PointerStruct * s);
	void SimplePointerStructOut([out] struct PointerStruct * s);
	void ConformantStructIn([in] struct ConformantStruct * s);
	void ConformantStructOut([in, out] struct ConformantStruct * s);
	void ConformantPointerStructIn([in] struct ConformantPStruct * s);
	void ConformantPointerStructOut([in, out] struct ConformantPStruct * s);
	void ConformantVaryingStructIn([in] struct ConformantVStruct * s);
	void ConformantVaryingStructOut([out] struct ConformantVStruct * s);
/* these two should generate hard structs which are more efficient than the complex
 * structs MIDL actually generates */
	void HardStructIn([in] struct HardStruct * s);
	void HardStructOut([out] struct HardStruct * s);
	void ComplexStructIn([in] struct ComplexStruct * s);
	void ComplexStructOut([in] struct ComplexStruct * s);
/* unions */
	void EncapsulatedUnionIn([in] Encapsulated * u);
	void EncapsulatedUnionOut([out] Encapsulated * u);
	void NonEncapsulatedUnionIn([in] short type, [in, switch_is(type)] union NonEncapsulated * u);
	void NonEncapsulatedUnionOut([in,out,ref] short *type, [out, switch_is(*type)] union NonEncapsulated * u);
/* transmit_as */
#if 0 /* need to write to/from/free routines */
	typedef [transmit_as(long)] char XMITAS;
	typedef long REPAS;
	void TransmitAsIn([in] XMITAS s);
	void TransmitAsOut([out] XMITAS * s);
	void RepresentAsIn([in] REPAS s);
	void RepresentAsOut([out] REPAS *s);

	void RangeIn([in, range(0, 100)] long l);
	void ByteCount([in] long cbBuffer, [out] struct PointerStruct * s);

	error_status_t ErrorStatusT([out] error_status_t * funcstatus);

-------------- next part --------------
    implicit_handle (handle_t hello_IfHandle)
interface Tests
#if 0
	typedef [represent_as(FakeString)] REPAS;
	[fault_status] ErrorStatusT([comm_status] funcstatus);
#if 0
	ByteCount([byte_count(cbBuffer)] s);

More information about the wine-devel mailing list