News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

C++ masm32 procedur

Started by ragdog, August 14, 2011, 04:56:40 PM

Previous topic - Next topic

ragdog

Hi

I try to code a plugin and can only found a c++ example

have this procedur 4 dwords?

static int menu_handler( t_table* pTable, wchar_t* pName, ulong index, int nMode )
{

masm32:

Menu_handler Proc pTable:DWORD,pName:DWORD,index:DWORD,nMode:DWORD

is this Right?


ragdog

No Horton

this is for calling a decorated C++ function from MASM.

I translate this procedur from c++ to masm32 and i know not if have this procedur 4 dWords?!

redskull

The short answer: probably.

The long answer: you can't ever say for sure.  C++ compilers can pretty much pass things anyway they please, so unless they specifically call it out somewhere, you just have to hope that they do it the "normal" way.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

ragdog


redskull

Strange women, lying in ponds, distributing swords, is no basis for a system of government

ragdog

Thanks i have it solved with

Menu_handler Proc C pTable:DWORD,pName:DWORD,index:DWORD,nMode:DWORD

Now have i a other question to fill this structur

C++


typedef struct t_menu {                // Menu descriptor
  wchar_t        *name;                // Menu command
  wchar_t        *help;                // Explanation of command
  int            shortcutid;           // Shortcut identifier, K_xxx
  MENUFUNC       *menufunc;            // Function that executes menu command
  struct t_menu  *submenu;             // Pointer to descriptor of popup menu
  union {
    ulong        index;                // Argument passed to menu function
    HMENU        hsubmenu;             // Handle of pulldown menu
  };
} t_menu;

;// menu that will appear in the main menu. Note that this menu
;// must be static and must be kept for the whole duration
static t_menu mainmenu[] = {
  { L"Menuentry",
       L"MenuInfo",
       0, MenuentryCallback, NULL, 0 },
  { L"Menuentry2",
       L"MenuInfo2",
       0, Menuentry2Callback, NULL, 0 },
  { L"|Menuentry3",
       L"MenuInfo3",
       0, Menuentry3Callback, NULL, 0 },
  { NULL, NULL, 0, NULL, NULL, 0 }
};


Here is my tryed translate but it works not correct can any Translate it right?

Masm32


t_menu STRUCT
Name1 DWORD ? ; Menu command
help DWORD ? ; Explanation of command
shortcutid DWORD ? ; Shortcut identifier, K_xxx
menufunc DWORD ? ; Function that executes menu command
submenu DWORD ? ; Pointer to descriptor of popup menu
;union t_menu
index DWORD ? ; Argument passed to menu function
hsubmenu DWORD ? ; Handle of pulldown menu
;ENDS
t_menu ENDS


WSTR Menuentry ,"entry"
WSTR MenuentryInfo,"entry info"
WSTR Menuentry2 ,"entry2"
WSTR MenuentryInfo2,"entry info2"
WSTR Menuentry3 ,"entry3"
WSTR MenuentryInfo4,"entry info3"

MainMenu  t_menu <Menuentry,MenuentryInfo,NULL,MenuentryCallback,NULL ,0>
          t_menu <Menuentry2,MenuentryInfo2,NULL,Menuentry2Callback,NULL ,0>
          t_menu <Menuentry3,MenuentryInfo3,NULL,Menuentry3Callback,NULL ,0>


greets

ragdog

I have found this bug i decomment "union   t_menu"

t_menu   STRUCT
   Name1 DWORD ? ; Menu command
   help DWORD ? ; Explanation of command
   shortcutid DWORD ? ; Shortcut identifier, K_xxx
   menufunc DWORD ? ; Function that executes menu command
   submenu DWORD ? ; Pointer to descriptor of popup menu
   
   
   union   t_menu
   index DWORD ? ; Argument passed to menu function
   hsubmenu DWORD ? ; Handle of pulldown menu
   ENDS
t_menu      ENDS

How i can fill this index " Argument passed to menu function"?

MainMenu   t_menu <Menuentry,MenuentryInfo,NULL,MenuentryCallback,0,1>

If i add the 1 have i this error
error A2138: invalid data initializer
error A2036: too many initial values for structure

baltoro

RAGDOG,   
I can see why you are confused. A C++ Union really has no counterpart in assembly language. Here is the MSDN documentation for: Unions. I never use unions when I code in C++, because they're not that useful. They are a only a convenience  Essentially, they give you a way to access some data in several different ways (syntactically). C++ compilers (like Visual Studio) have type checking, and the code will fail to compile if you don't access the union data using one of the declared types (in this case, a ulong or HMENU). In C++, both the ulong and the HMENU are typedef'ed from a DWORD. To convert this to assembly, just ignore the union declaration (delete the union declaration) and leave one or both of the DWORDs in your structure. For the code example you posted, the simplest method would be to just make it a single structure.

union   t_menu
   index DWORD ? ; Argument passed to menu function
   hsubmenu DWORD ? ; Handle of pulldown menu
   
Here, the index DWORD and the hsubmenu DWORD are referring to the same exact data (DWORD), and so having both types in your structure is redundant. And, of course, the MASM compiler has no idea what a union t_menu is,...
Baltoro

jj2007

Quote from: baltoro on August 15, 2011, 10:08:10 PM
RAGDOG,   
I can see why you are confused. A C++ Union really has no counterpart in assembly language.

It has, it has, but it's tricky and badly documented. The example below, modified from Chapter 5 of the Masm Programming Guide, works just fine with ML (all versions) and gets assembled by JWasm (but yields a different result).


Quoteinclude \masm32\include\masm32rt.inc

ITEMS       STRUCT 
  Iname     BYTE      'Item Name'
  Inum      WORD      ?
  UNION     ITYPE                ; UNION keyword appears first
    oldtype BYTE      123          ;   when nested in structure.
    newtype WORD      12345          ;   (See "Nested Structures
  ENDS                           ;   and Unions," following ).
ITEMS       ENDS     


.DATA
Item   ITEMS   <'Bolts', 126>   ; Overrides default value of first
                                 ;   2 fields; use default of the third field
.code
start:   movzx eax, Item.ITYPE.oldtype
   inkey str$(eax), " for item.oldtype"
   exit

end start

Output: 123 for item.oldtype

Basically. it means you cannot initialise the UNION member in the .data section; instead, you omit it and get the first default value.
::)

baltoro

Wow,...Thanks, Jochen for saving my ass,... :eek
I had no idea. Must be my Union phobia,...
Baltoro

GregL

jj2007,

So, don't initialize it in the DATA section, do it in your code. No limitations.

INCLUDE \masm32\include\masm32rt.inc

ITEMS STRUCT
    Iname BYTE       ?
    Inum  WORD       ?
    UNION ITYPE
        oldtype BYTE ?
        newtype WORD ?
    ENDS
ITEMS ENDS


.DATA

    Item ITEMS <>

.CODE

  start:

    mov Item.ITYPE.oldtype, 123

    movzx eax, Item.ITYPE.oldtype
    inkey str$(eax), " for item.oldtype"
   
    mov Item.ITYPE.newtype, 12345
   
    movzx eax, Item.ITYPE.newtype
    inkey str$(eax), " for item.newtype"
   
    exit

END start


jj2007

Quote from: GregL on August 16, 2011, 02:55:17 AM
jj2007,

So, don't initialize it in the DATA section, do it in your code. No limitations.


Sure, that is always possible. But still, the documentation steers cautiously away from giving a full example for UNION. They know why. Add the case where the UNION is not the last member of the STRUCT, and the mess is complete :bg

ToutEnMasm


Seems here that the first argument "Iname BYTE       " broke the alignment and is responsible of the problem.
Try to put a align directive before to solve it.

jj2007

Quote from: ToutEnMasm on August 16, 2011, 07:07:49 AM

Seems here that the first argument "Iname BYTE       " broke the alignment and is responsible of the problem.
Try to put a align directive before to solve it.


There is no alignment problem, ToutEnMasm.



In the meantime, I found the correct syntax for declaring the UNION:
QuoteItem1   ITEMS   <"abcdef", 12345, {99}>

Which does not solve all problems, though. It remains very messy. Inter alia, JWasm produces different values, only the UNION gets initialised by its default value, and I was able to cause an exception in ml.exe version 6.14 simply by writing
QuoteITEMS STRUCT STRUCTALIGN 4
(I know it's a syntax error, but is it worth a GPF? ::))

Have fun. My conclusion is don't use UNIONs, it's too buggy.

include \masm32\include\masm32rt.inc

ITEMS STRUCT
  Iname BYTE 'Item Name' ; caution: the text "Item Name" defines the length of Iname, here: 9 chars
  Inum WORD 3333h
  UNION ITYPE ; UNION keyword appears first
    oldtype BYTE 123 ; when nested in structure.
    newtype WORD 12345 ; (See "Nested Structures
  ENDS ; and Unions," following ).
ITEMS ENDS


.DATA ; see Chapter 5 of Masm Programming Guide
Item1 ITEMS   <"abcdef", 12345, {99}> ; Overrides default values
Item2 ITEMS   <"",?,{}> ; Should take default values, ok for UNION but no success for string and WORD

.code
start:
; mov edx, offset Item1.Iname ; check in memory...
; int 3
print offset Item1.Iname, " as string (the '90' is part of WORD 12345)", 13, 10
; mov edx, offset Item1.Inum ; the WORD
; int 3
movzx eax, Item1.Inum
print str$(eax), " for Inum", 13, 10
movzx eax, Item1.ITYPE.oldtype
print str$(eax), " for Item1.oldtype", 13, 10
movzx eax, Item1.ITYPE.newtype
print str$(eax), " for Item1.newtype", 13, 10

print offset Item2.Iname, " as string", 13, 10
; mov edx, offset Item2.Inum ; the WORD
; int 3
movzx eax, Item2.Inum
print str$(eax), " for Inum", 13, 10
movzx eax, Item2.ITYPE.oldtype
print str$(eax), " for Item2.oldtype", 13, 10
movzx eax, Item2.ITYPE.newtype
inkey str$(eax), " for Item2.newtype"

exit

end start