The MASM Forum

General => The Workshop => Topic started by: Biterider on November 11, 2021, 03:18:09 AM

Title: Translation
Post by: Biterider on November 11, 2021, 03:18:09 AM
Hi
I have a bit of troubles with the translation of this C structure

typedef struct tagEXCEPINFO {
    WORD  wCode;
    WORD  wReserved;
    BSTR  bstrSource;
    BSTR  bstrDescription;
    BSTR  bstrHelpFile;
    DWORD dwHelpContext;
    PVOID pvReserved;
    HRESULT (__stdcall *pfnDeferredFillIn)(struct tagEXCEPINFO *);
    SCODE scode;
} EXCEPINFO, * LPEXCEPINFO;

In particular, the red marked member is identical to a function prototype.
Does anyone know how to distinguish whether it is a structure member or a function proto in this case?

The goal is for a translator, in this case h2incX, to have an indication of how to proceed.

Biterider
Title: Re: Translation
Post by: Greenhorn on November 11, 2021, 07:16:42 AM
Hi Biterider,

in this case you can use the "*" as an indicator that it is a function pointer.

HRESULT (__stdcall *pfnDeferredFillIn)(struct tagEXCEPINFO *);

h2incX gives me this translation:

EXCEPINFO   struct
   wCode         WORD   ?
   wReserved         WORD   ?
   bstrSource      BSTR   ?
   bstrDescription   BSTR   ?
   bstrHelpFile      BSTR   ?
   dwHelpContext      DWORD   ?
   pvReserved      PVOID   ?
protoEXCEPINFO_pfnDeferredFillIn typedef proto WINSTDCALLCONV :ptr tagEXCEPINFO
pEXCEPINFO_pfnDeferredFillIn typedef ptr protoEXCEPINFO_pfnDeferredFillIn
   pfnDeferredFillIn   pEXCEPINFO_pfnDeferredFillIn   ?
   scode   SCODE   ?
EXCEPINFO   ends
LPEXCEPINFO typedef ptr EXCEPINFO


You can take a look at the source code of h2incX ... CIncFile.asm, line 1934

;--- determine if it is a "function" or "function ptr" declaration

IsFunctionPtr proc

local   dwCntBrace:dword
local   bRC:dword
local   sis:INPSTAT

      invoke SaveInputStatus, addr sis
      inc m_bSkipPP
      mov dwCntBrace, 1
      mov bRC, FALSE
      .while (dwCntBrace)
         invoke GetNextToken
         .break .if (!eax)
         lea ecx, sis
         invoke IsIfLevelActive
         .continue .if (CARRY?)          
         .if (word ptr [eax] == '(')
            inc dwCntBrace
         .elseif (word ptr [eax] == ')')
            dec dwCntBrace
         .endif
      .endw
      .if (eax)
         invoke GetNextToken
         .if (eax && (byte ptr [eax] == '('))
            mov bRC,TRUE
         .endif
      .else
         dprintf <"%s, %u: unexpected eof",lf>, m_pszFileName, m_dwLine
      .endif
@exit:
      dec m_bSkipPP
      invoke RestoreInputStatus, addr sis
      mov eax, bRC
      ret

IsFunctionPtr endp



Kind regards
Greenhorn
Title: Re: Translation
Post by: Biterider on November 11, 2021, 07:24:41 AM
Thanks Greenhorn
I think it is clear, that it is a function pointer declaration, but why it is also a structure member?
Or is a function declaration automatically a structure member if it is declared inside a structure?

Biterider
Title: Re: Translation
Post by: Greenhorn on November 11, 2021, 07:32:57 AM
I would say yes, as long as it is a function pointer.
Title: Re: Translation
Post by: Biterider on November 11, 2021, 07:37:00 AM
 :thumbsup:
Title: Re: Translation
Post by: mineiro on November 11, 2021, 07:52:26 AM
I think that can be a callback function. I have see this in object oriented programming like gtk+ as an example.
In gtk, some functions depends of other callback functions, I think thats because hierarchy.

An example is:
g_slist_insert_sorted proto  list:ptr GSList, data:gpointer, function:GCompareFunc

Now looking to prototype GCompareFunc:
LIBRARY: glib CALLBACK: gint GCompareFunc (gpointer a, gpointer b)

So, when I call g_slist_insert_sorted, I need give other function as a pointer to compare data and return result.
Will be something like:
invoke g_slist_insert_sorted, addr my_list, add my_data, addr my_compare

my_compare proc first:ptr,second:ptr
ret
my_compare endp

It's not necessary to be my_compare function, generally exists more than one function in same library that do the job, so, user can choose whats better to deal with specific data.
From what I have seen these type of functions deals with data transform/sort. So, from this example, a list can store pointers/numbers/strings. The'res no universal function to deal with these data types, so user must choose what data type list will store.
Title: Re: Translation
Post by: HSE on November 11, 2021, 11:05:04 AM
Hi Biterider!

HRESULT (__ stdcall .....  Is a COM Method, and structure is an Interface (Raymond Chen 09/09/2020)

Regards, HSE.
Title: Re: Translation
Post by: Biterider on November 12, 2021, 05:25:14 AM
Hi HSE
Very good link.  :thumbsup:
It will surely help with the next thing I had to revise, the COM declarations!

Biterider