.data?
mystruct ASTRUCT<>
.code
lea eax, dword ptr MyFunction
mov mystruct.fptr, eax


push parm1 ;a way to clean it up from here
push parm2
push parm3
call mystruct.fptr ; to here


I seem to remember reading something about mcall?

Thanks.
Posted on 2002-04-13 13:59:04 by ThoughtCriminal
I don't know if this is really any help to you but i founded a sure replacement for invoke.

see CMAX TO BIRAKE post.

I went with ParReverse posted by stryker. I tried bitRAKE macro but i could not get it to work, but than again i was to lazy after i found that ParReverse nearly repaced everything but Get Moduule Handle or the Get Command Line.

But it did the job for everything else with no problem....I used to not like macros, i don't really know why, but I like them NOW...
Posted on 2002-04-13 16:29:11 by cmax
You can set the type of the structure member like this:


SomeFunction PROTO STDCALL :DWORD

ptrSomeFunction typedef PTR SomeFunction

SomeStruct STRUCT
...
fptr ptrSomeFunction ?
...
SomeStruct ENDS

Then just call:

invoke someStructInstance.fptr, 0


Thomas
Posted on 2002-04-13 16:45:42 by Thomas
Or:


invoke (MessageBox ptr [something]),.....


I didn't test it but should be something like this.

Thomas
Posted on 2002-04-13 16:47:31 by Thomas
Thanks for the replies. I think I need to explain a little better.

I cannot use invoke with a function pointer, because invoke only works with prototyped functions. Unless there is a way to prototype a funtion pointer, invoke will not work.

The verbose method of pushing parms and calling will work.

I probly should not have put 1,2,3 after the parms. Order is not the problem. I am assuming the parameter order is always correct _stdcall.

I don't know anything about making macro, and a Google search didn't turn up any tuts. I am sure that by now someone else has realized they can't prototype a function pointer. I figure by now someone has made a macro wrap pushing of paramaters and calling. If there already is one, and it could be considered standard, I'd prefer to use it before trying my own. I'm working on a high level data structure with embedded functions. I'd like to give the user the option of using the verbose method, or using a macro. I don't want to confuse things by making a macro that already exists.

Thanks for the help, I've already learned something from the previous posts.
Posted on 2002-04-14 01:48:47 by ThoughtCriminal
Well i guess i will clarify for you :grin: (Thomas has the right solution above, just a little short of detail).

I cannot use invoke with a function pointer, because invoke only works with prototyped functions. Unless there is a way to prototype a funtion pointer, invoke will not work


There Is!! If there wasnt, our OOP model wouldnt have gotten off the ground :)

Anywho, here are extracts of our OOP model solutions to get the dirty work your looking for done:


[b]You dont even need macros if you dont want to[/b]

Type1 [b]TYPEDEF PROTO[/b] :DWORD, :BYTE, :WORD
Type2 [b]TYPEDEF PROTO[/b] :DWORD
Type3 [b]TYPEDEF PROTO[/b]

.code

...
mov edx, FunctionPointer
invoke [b]Type1 PTR[/b] [edx], ecx, al, bx
...
mov edx, FunctionPointer
invoke [b]Type2 PTR[/b] [edx], ecx
...
mov edx, FunctionPointer
invoke [b]Type3 PTR[/b] [edx]


They you go.. Enjoy..
:alright:
NaN
Posted on 2002-04-14 03:33:55 by NaN
Wow, not what I was looking for but better!!!:eek:

By just making several TYPEDEFs, ie.
(stealing you stuff)



Type1 TYPEDEF PROTO :DWORD,
Type2 TYPEDEF PROTO :DWORD,DWORD
Type3 TYPEDEF PROTO :DWORD,DWORD,DWORD


It looks like you can do function overloading!!:grin:

Or at least varying amounts of parameters depending on what is needed at the time.(just what I may need)

So simple too.
You've been a big help NaN.
Posted on 2002-04-14 07:49:36 by ThoughtCriminal
ThoughtCriminal can you give an example (maybe source) on your idea of function overloading?

Not sure I followed the last bit from Thomas -> Nan -> You...

I would hope someone could clarify..

Sliver
Posted on 2002-04-14 13:09:47 by Sliver
Ok...



SetLayeredWindowAttributes PROTO :DWORD, :DWORD, :BYTE, :DWORD

1) invoke (TYPE SetLayeredWindowAttributes) ptr [i]register[/i], <parms>
2) invoke (TYPE SetLayeredWindowAttributes) ptr [[i]register[/i]], <parms>
3) invoke (TYPE SetLayeredWindowAttributes) ptr [[i]variable[/i]], <parms>


1 & 2 work like expected. 3, however, ends up calling "variable", not what
"variable" points to. IE, if "variable" is located at offset 401110 in
memory, you'll see a "call 401110" not "call dword ptr [401110]".

Bitrake, any ideas?
Posted on 2002-04-14 16:30:00 by f0dder
I tackled this issue just last night while making revisions to the OOP model.

I discovered that there is no way of MASM to determin a value when using #3 with a variable. This is because masm NEEDS to put something in the field when compiling...

#3 is being used by assuming that the data held at 'Variable' will be set... problem is, this is a RUN-TIME setting event.

Since Masm doesn know the contents at compile time, so it simply defaults to using the Variable address instead. For this reason you CANT do this, and must provide a register, which can then be trusted to be properly filled at runtime.

My work around was with macro's:

METHOD .ClassName.Method, Param, Param, ...

.ClassName.Method is all one Param, and i parse it into pieces: Variable, ClassName, and Method. Then i ask if 'Variable' is a register. If not i add an extra line of assembly:

mov edx, Variable

And continue as if it was now done as :

METHOD .ClassName.Method, Param, Param, ...


Anywho.. there is my findings..
:alright:
NaN
Posted on 2002-04-14 17:30:18 by NaN
Well, there *is* an opcode for "call indirect", and it sucks that I can't
figure out how to make masm use it for case #3...
Posted on 2002-04-14 17:42:58 by f0dder
I know there is, but the only way i know of is to manually force the OPCODES to file by doing 'db xx, xx, offset Variable'

I never tried such things however.... :-/

:alright:
NaN
Posted on 2002-04-14 20:22:01 by NaN
Sorry Sliver, currently my ideas on function overloading are confined to the realm of 'wild speculation' based on NaN's post.

I'm not sure #3 might work for me. Heres what I am doing:



.data?
mystruct STRUCT<>
.code

lea edx, dword ptr MyFunction;
;lea eax,[@ILT+0(_MyFuntion@16) (401005h)

mov mystruct.handle, edx;first struct element=pointer to function

push something
push something
push something
call mystruct.handle;diss=call dword ptr[myString (4043A4h)]


The trick is in the call. I call the address of my variable, but the jump table contains the address of my function.

Ahh just tried this, and it works:



call dword ptr mystruct


got to work now
Posted on 2002-04-14 22:50:19 by ThoughtCriminal
Obviously there's no problem whatsoever if you do the "call dword ptr"
manually - this whole thing is about making invoke work...
Posted on 2002-04-15 07:30:29 by f0dder

Obviously there's no problem whatsoever if you do the "call dword ptr"
manually - this whole thing is about making invoke work...


True. I posted exactly what I'm doing just in case someone knows a trick to make it with invoke.
Posted on 2002-04-15 08:02:15 by ThoughtCriminal
I've gotten this one to work with invoke:
3) invoke (TYPE SetLayeredWindowAttributes) ptr [variable], <parms>

Well, kinda in a way, or more like:
3) invoke (TYPE SetLayeredWindowAttributes) ptr [label], <parms>

Heres the details:
P4		TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD


.data?
myString SSTRING<>
.code
invoke P4 ptr [handle], ADDR myString, 1, 4096, 8192

sstring proc saddr:DWORD, ftype:DWORD, src:DWORD, dst:DWORD
handle LABEL DWORD
mov ebx, [ebp+8] ;address of passed SSTRING
mov edx, [ebp+12] ;function to execute
.
.
.
etc.

I can call 'handle' and get the structure I want. And yes, the stack is in order. Here's some dissassembly and code bytes:


invoke P4 ptr [handle], ADDR myString, 1, 4096, 8192
00401107 68 00 20 00 00 push 2000h
0040110C 68 00 10 00 00 push 1000h
00401111 6A 01 push 1
00401113 68 A4 43 40 00 push offset myString (4043A4h)
00401118 E8 B3 00 00 00 call sstring (4011D0h)

and inside the proc:

sstring proc saddr:DWORD, ftype:DWORD, src:DWORD, dst:DWORD
004011D0 55 push ebp
004011D1 8B EC mov ebp,esp
handle LABEL DWORD
mov ebx, [ebp+8] ;address of passed SSTRING
004011D3 8B 5D 08 mov ebx,dword ptr [saddr]
mov edx, [ebp+12] ;function to execute
004011D6 8B 55 0C mov edx,dword ptr [ftype]
mov esi, [ebp+16] ;source/size1
004011D9 8B 75 10 mov esi,dword ptr [src]
mov edi, [ebp+20] ;dest/size2
004011DC 8B 7D 14 mov edi,dword ptr [dst]


Its 6AM, I need to get sleep now. I have not tested this much.
Enjoy the info:cool: :grin:
Posted on 2002-04-17 15:57:00 by ThoughtCriminal
That's still not what wanted - it does "call sstring" and not "call ".
Too bad, I just got my hopes up :(
Posted on 2002-04-17 16:03:26 by f0dder
Sorry, Fodder. I'm not trying to design an OOP framework. I did want to share an approach that got different results from invoke than just callng the variable. I may still try some experiments.

Try some crazy things that might work, or just not compile.
Posted on 2002-04-17 21:50:42 by ThoughtCriminal
f0dder, here you go. :)
.data

P4 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD

P4P TYPEDEF PTR P4

Jump dd OFFSET JumpHere

route STRUCT
tag dd ?
j P4P ?
route ENDS

MyRoute route <>
.code
; direct
invoke P4 ptr [JumpHere],4,3,2,1
; indirect
invoke P4P ptr [Jump],4,3,2,1
; indirect
invoke [MyRoute.j],4,3,2,1
; indirect
invoke [ebx].route.j,4,3,2,1
With a creative UNION, a general elegant solution is posible, imo. :)

Something like:
	P0 TYPEDEF proto

P1 TYPEDEF proto :DWORD
P2 TYPEDEF proto :DWORD, :DWORD
P3 TYPEDEF proto :DWORD, :DWORD, :DWORD
P4 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD
P5 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P6 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P7 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P8 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
P9 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

P0P TYPEDEF PTR P0
P1P TYPEDEF PTR P1
P2P TYPEDEF PTR P2
P3P TYPEDEF PTR P3
P4P TYPEDEF PTR P4
P5P TYPEDEF PTR P5
P6P TYPEDEF PTR P6
P7P TYPEDEF PTR P7
P8P TYPEDEF PTR P8
P9P TYPEDEF PTR P9

pr UNION
i0 P0P ?
i1 P1P ?
i2 P2P ?
i3 P3P ?
i4 P4P ?
i5 P5P ?
i6 P6P ?
i7 P7P ?
i8 P8P ?
i9 P9P ?
pr ENDS
Now just tag any indirect invoke with the proto you want to use: invoke .pr.i4,4,3,2,1. Some will ask why? Well, this abstracts the whole thing to a single public union - the rest of the typedefs/protos can be psuedo-private.
Posted on 2002-04-17 22:19:30 by bitRAKE
Nice one Bitrake!!! I haven't gotten around to trying unions yet. Guess I wont have to.

But to really pass the Fodder test, you compiled code needs to look like:



push (blah)
push (blah)
push (blah)

[B]call [Jump][/B]
Posted on 2002-04-17 23:34:07 by ThoughtCriminal