My c++ is pretty damn rusty (and not that strong to begin with). I'm trying to translate a c++ dll into masm. There's only one exported function and one of it's params is defined as "void far * far *vdatptr" and is commented as "a far array of far pointers". Theoretically I just have to setup that param as "vdatptr:DWORD" and then just increment it to access the other pointers right?

Other than that I don't understand the "void far * far *vdatptr" syntax. I'd be grateful if someone could explain that to me.

Posted on 2003-04-04 17:29:32 by Will
Just take it that it is a pointer to pointer.

I would do something like

mov eax,vdatptr
mov eax,[eax]
Posted on 2003-04-04 23:03:27 by roticv
worked like a charm roticv!

Posted on 2003-04-05 14:01:06 by Will
Either this week has really been as long and taxing as it feels, or I'm a complete idiot, but I've got another question about this stuff.

I'm trying to replace the value of a variable that's passed to my dll. The example c++ line of code for this is:
*(int *)vdatptr[0]) = 123

I am at a complete loss on how to translate that to masm though. Again, any assistance would be greatly appreciated. :)

Posted on 2003-05-16 14:41:22 by Will
Originally posted by Will
I'm trying to replace the value of a variable that's passed to my dll. The example c++ line of code for this is:
*(int *)vdatptr[0]) = 123

Some basic principles:

Variable arr is a pointer to the start of the array, x is a zero-based index into the array. The array is indexed by element, not by byte like in asm. In asm, this would translate to a memory reference at the address of the array plus size_of_one_element * x.

This is a C-style cast of an expression. It basically changes the type of expression to type. C defines some standard conversions (like float to int). On pointers to primitives (int, float, double, etc.) it does nothing at assembly level, it only gives the pointer a different type. If a primitive itself is cast (e.g. float to int) it might perform some kind of conversion (rounding down, extending bits, etc.).

Dereferences a pointer (the parenthesis may be omitted if possible), meaning it extracts the value the pointer is pointing at. It's the same as doing a memory reference mov reg, . If this kind of thing is the left hand side of an expression (like your example), it means you want to put something at the place the pointer is pointing to (compare: mov , reg).

So your code *((int*)vdatptr[0]) = 123 works as follows:
Get me the first element in the vdatptr array.

mov eax, [vdatptr] ; assuming vdatptr is a dword, eax now is the pointer it contains
mov eax, [eax] ; assuming the elements of the array are dword sized, this gets the first element in eax

Change the type of the value you got from the array to an int pointer (type that points to an integer). This produces no code.

*(X) = 123 (where X is the integer pointer (now eax), (int*)vdatptr[0])
Dereferences the pointer X and tells the compiler it wants the decimal value 123 at that place.

mov dword ptr [eax], 123

That's it!

Posted on 2003-05-16 15:05:46 by Thomas
Well long story short, the dll function is called from a proprietary scripting language that seems to pass variables by value and not by reference. That's (your method) how I had tried it originally, but it didn't work so I thought that I must've been doing something wrong. That c snippet is from an email from one of the programmers who developed the scripting language. Either he misunderstood my question or I misunderstood his answer....

Oh well, thanks for the quick and highly informative reply Thomas.

Posted on 2003-05-16 15:40:21 by Will
I've received email confirmation from one of the developers of the scripting language that the script does indeed pass variables byref so I should be able to change them this way.

mov eax,varArgs
mov eax,[eax + 4]
mov byte ptr[eax],'A'

Shouldn't the above code put the letter 'A' into the 1st byte of that string?

When I print the string from the script after returning from the function call, the string hasn't changed.

Posted on 2003-05-21 12:05:12 by Will

I seem to have stumbled on another peculiarity of this scripting language. In the dlgevent (its msgloop), under one button I put the dll call. Then under another button I put the writing of that string to test whether I could change it or not. So I cut/pasted the writing the string line of code to directly after the dll call in that portion of the event handler code and it worked like a charm. That's incredibly weird.
Posted on 2003-05-21 12:46:21 by Will