Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
QM translation of C++
#1
Hi Gintaras, hi all

Gintaras, i need some explanations on the LameWavToMp3 macro.

I understand that QM handles some C++ syntax differently, and I understand 90% of the QM code, but some are beyond my
understanding.

1. type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal

it's the translation of this

struct {

DWORD dwSampleRate;
BYTE byMode;
WORD wBitrate;
BYTE byEncodingMethod;

} aac;

why WORD wBitrate is converted to [+1]@wBitrate and not simply @wBitrate? i think it's an offset stuff but can't get it.

2. type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac

i understand that it's QM translation for an union , but why use it? offset again?

____BE_CONFIG11'mp3
[]____BE_CONFIG12'LHV1
[]____BE_CONFIG13'aac

i speak about [] before variable names....why mandatory in QM and not used in C?

3. can you explain this conversion?

typedef void* HBE_STREAM;
typedef HBE_STREAM *PHBE_STREAM;
typedef unsigned long BE_ERR;

QM:

type BE_ERR = #
type HBE_STREAM = #

Thanks!
#2
1. Yes, offset 1 from byMode. Without it would be offset 2. The C header file contains this:
#pragma pack 1

Or can be this, it works like C #pragma pack 1:
type ____BE_CONFIG11 dwSampleRate !byMode @wBitrate bPrivate bCRC bCopyright bOriginal [pack1]

2. In QM, nonstandard member offsets must be explicitly specified. Including union members. Like in C#. In C/C++ for it are used keyword union and directive #pragma pack.

More info in QM help topic "Type member alignment; unions".

3. Code "type TYPE = #" in a ref file means "there is no conversion of TYPE to QM; in QM use int instead of TYPE". Here # is int type character.

BE_ERR is unsigned long. QM does not have unsigned int.

HBE_STREAM is void*. Here void* is used to define a handle. In QM could be used byte*, but easier is to use int for handles. Like we use int for window handles, although in C it is a pointer typedef.
#3
for question one, as it's a bit tough to comprehend

i copied the wrong structure, its actually
struct {

DWORD dwSampleRate; // 48000, 44100 and 32000 allowed
BYTE byMode; // BE_MP3_MODE_STEREO, BE_MP3_MODE_DUALCHANNEL, BE_MP3_MODE_MONO
WORD wBitrate; // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed
BOOL bPrivate;
BOOL bCRC;
BOOL bCopyright;
BOOL bOriginal;

} mp3;

so type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal

holds in bytes size:

4/1/2/1/1/1/1

so dwSampleRate has offset 0, bymode offset 4, wBitrate offset 5

pack 1 is used to set wBitrate to 6, so it is offset is divisible by it's size, 2.
is this correct?
is yes, is size of bymode 2 instead of 1 then by padding, and then strucuture size is 12 instead of 11 at the original declaration?

would it be possible to invert bymode and wBitrate to make it aligned correctly (1 byte should be always well aligned)

____BE_CONFIG11 dwSampleRate @wBitrate !byMode bPrivate bCRC bCopyright bOriginal

then we have in sizes

4/2/1/1/1/1/1 and no pragma required, as those variables don't seem to be in the exact order in the struct declaration, or i'm mistaken on that point.

will study other answers later...
#4
In C: #pragma pack 1 sets wBitrate offset = 5. Without it would be 6.
In QM: [pack1] or [+1] sets wBitrate offset = 5. Without it would be 6.

To see type size use out sizeof(TYPE).
To see member offset use out &x.member-&x.

>would it be possible to invert bymode and wBitrate
no.
#5
that's exactly where i'm lost, even with extensive researches.

Quote:wBitrate offset = 5. Without it would be 6.

i must then suppose that the compiler would align automagically bymode to 2 byte to fit alignment of WORD wBitrate and that the C headers use pragma to
force it to be it's "right" alignment (for memory saving i guess)?



as
DWORD dwSampleRate => size 4 bytes offset 0

BYTE byMode => size 1 byte offset 4

WORD wBitrate size 2 bytes, offset should be 5 not 6 (4+1)

i will play with sizeof(i 'm away from my laptop right now) later to understand.

Quote:>would it be possible to invert bymode and wBitrate
no.

why? the order of the variables does not seem to be important...
#6
If the order is not important, then also don't need special packing. I thought the type is used with a dll function.

When defining private types, I usually order members like you said, to avoid gaps. But actually it is useful only if the type is used in large arrays or in large stack or saved in files.
#7
Quote:If the order is not important, then also don't need special packing. I thought the type is used with a dll function.

yes, i missed that and now i understand why pragma is used, it's indeed a dll function in bladeenc.dll

So order IS important as the call of the procedure must match the headers one.....

------------------------------------------------------------------
playing with sizeof, using pragma it's 23, 24 without it.

so this way is explicit packing (you say what variable to pack)

type ____BE_CONFIG11 dwSampleRate !byMode [+1]@wBitrate bPrivate bCRC bCopyright bOriginal

and this one is implicit or automatic, the argument seems to do it automatically

type ____BE_CONFIG11 dwSampleRate !byMode @wBitrate bPrivate bCRC bCopyright bOriginal [pack1]

Is this statement correct?


but i wonder why so much hassle to gain one byte meory, and seems from my readings that it's less perfomant than odd numbers of bytes.


2.
Quote: In QM, nonstandard member offsets must be explicitly specified. Including union members. Like in C#. In C/C++ for it are used keyword union and directive #pragma pack.

type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac

the empty brackets do mean to use previous packing method then, correct? but they are not the same size....
or is it just a convention for QM to work correctly?

3. ok, just translation of type to QM which own less types than C...i put them on a paper for further reference
#8
>Is this statement correct?
both correct.

>the empty brackets do mean to use previous packing method
no, it is like I wrote in QM help topic "Type member alignment; unions".
#9
yes from documentation

Quote:Empty brackets means same offset as of previous member

so here two empty brackets, for 2nd and third structure of the union.

So what does it mean as none of the brackets contain any number?????

Quote:type __BE_CONFIG1 ____BE_CONFIG11'mp3 []____BE_CONFIG12'LHV1 []____BE_CONFIG13'aac


here offset of struct contained in __BE_CONFIG1 is sized

24 for mp3
328 for LHV1
8 for aac

we could have waited for

type __BE_CONFIG1 ____BE_CONFIG11'mp3 [24]____BE_CONFIG12'LHV1 [352]____BE_CONFIG13'aac


can you explain a bit more?
#10
All offsets are 0.

Macro Macro515
Code:
Copy      Help
ref lame "lame_def"

lame.__BE_CONFIG1 x
out "%i %i %i    %i %i %i    %i" &x.mp3-&x &x.LHV1-&x &x.aac-&x  sizeof(____BE_CONFIG11) sizeof(____BE_CONFIG12) sizeof(____BE_CONFIG13)  sizeof(__BE_CONFIG1)
;0 0 0    24 328 8    328
#11
ok, so why is it useful then if all are 0?
only convention to translate C code to QM?
#12
__BE_CONFIG1 is union, not struct.
#13
so everytime i find an union in C code and want to convert in QM, I must use this
convention with empty brackets at the beginning of the second to last structure of the union?
#14
Yes.

C:
union X { int a; double b; byte c; };

QM:
type X int'a []double'b []byte'c

C#:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct X { [FieldOffset(0)] public int a; [FieldOffset(0)] public double b; [FieldOffset(0)] public byte c; };
#15
ok, understood, so simple in fact...
Going under the hood is sometimes hard.
thanks for your patience and knowledge Gintaras.


Forum Jump:


Users browsing this thread: 1 Guest(s)