Returning "nothing"/"null"

Hi,

I have a function that has a user defined type as its return type. That's fine, but in this particular situation sometimes there is nothing to return.

In other languages I work in I can deal with this quite well. In C I can return NULL instead of a pointer to a structure then check if we have anything like:-

if (structPtr = somefunction())
{
/* Do something with structPtr */
}

In Perl I can return undef and write a similar statement. In both cases I can do something conditionally based upon whether anything was returned.

How can I do something similar in VB? Can I? I know the C example isn't really the same because I'm returning a pointer to a struct, which is why it can be NULL. Perl just doesn't care. Which is nice.

In VB I don't believe I can return ByRef and return a null reference. I also can't do (as I expected, but I tried anyway):-

Set FunctionName = Nothing ' Function not an object.

or

FunctionName = vbNull ' Type mismatch

Thoughts? Or will I have to pass the struct byref in the parameter string and return a boolean stating whether the struct (or rather, instance of a type) has been populated?

Jonathan

###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

Comments

  • : Hi,
    :
    : I have a function that has a user defined type as its return type. That's fine, but in this particular situation sometimes there is nothing to return.
    :
    : In other languages I work in I can deal with this quite well. In C I can return NULL instead of a pointer to a structure then check if we have anything like:-
    :
    : if (structPtr = somefunction())
    : {
    : /* Do something with structPtr */
    : }
    :
    : In Perl I can return undef and write a similar statement. In both cases I can do something conditionally based upon whether anything was returned.
    :
    : How can I do something similar in VB? Can I? I know the C example isn't really the same because I'm returning a pointer to a struct, which is why it can be NULL. Perl just doesn't care. Which is nice.
    :
    : In VB I don't believe I can return ByRef and return a null reference. I also can't do (as I expected, but I tried anyway):-
    :
    : Set FunctionName = Nothing ' Function not an object.
    :
    : or
    :
    : FunctionName = vbNull ' Type mismatch
    :
    : Thoughts? Or will I have to pass the struct byref in the parameter string and return a boolean stating whether the struct (or rather, instance of a type) has been populated?
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :

    If you could figure out the address, you could probably use CopyMemory to make SomeFunction's return be Null but it'd be interesting to see how VB would handle it. Most likely, your only decent option is to return it through a parameter and return True/False. On the plus side, the code would look a little more similar to the C example you have above.

    [code]If somefunction(structPtr) Then
    'Do something with structPtr
    End If
    [/code]
  • : If you could figure out the address, you could probably use
    : CopyMemory to make SomeFunction's return be Null but it'd be
    : interesting to see how VB would handle it.
    Depends how it's working internally. If internally it returns a pointer, you could overwrite the return address on the call stack with CopyMemory. But if it has s space the size of the type on the stack allocated for the return value, then you can't do what you suggested. Even if it's a pointer then the function's return type is named as the structure so VB will probably flag up a type mismatch if you compare it to vbNull. That or try to dereference a NULL pointer and crash spectacularly.

    : Most likely, your only decent option is to return it through a
    : parameter and return True/False. On the plus side, the code would
    : look a little more similar to the C example you have above.
    :
    : [code]If somefunction(structPtr) Then
    : 'Do something with structPtr
    : End If
    : [/code]
    As suspected. But thought I'd check with "the expert"(s). ;-)

    KDL: On the note of your program that would allow you to execute assembly in a VB program. Do you know how to modify the current instruction pointer for a VB program? If so, the rest may be fairly easy - you would "simply" have to declare a bytearray, populate it with machine code and jump the current instruction pointer there. OK, it's not quite that simple - generating the machine code from the assembly is kinda interesting and you have to ensure you return to the right instruction. But it's the same kinda technique used in JIT. And some buffer overflow exploits.

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • : Depends how it's working internally. If internally it returns a pointer, you could overwrite the return address on the call stack with CopyMemory. But if it has s space the size of the type on the stack allocated for the return value, then you can't do what you suggested. Even if it's a pointer then the function's return type is named as the structure so VB will probably flag up a type mismatch if you compare it to vbNull. That or try to dereference a NULL pointer and crash spectacularly.
    :

    I believe that VB (and all other MS versions of Basic) use a copying method for ByRef parameters. That is: it copies your variable to another temp location, passes the temp location to the function and copies the data back on return.

    It'd still depend on whether or not VB is smart enough to handle a null pointer. I'd assume yes since it would have to be prepared to do so in the case of an external function doing just this (internal functions by us VB-ers wouldn't be supposed to be able to do this) and it does have minor support for null.

    : As suspected. But thought I'd check with "the expert"(s). ;-)
    :

    I think I'm being laughed at.

    : KDL: On the note of your program that would allow you to execute assembly in a VB program. Do you know how to modify the current instruction pointer for a VB program? If so, the rest may be fairly easy - you would "simply" have to declare a bytearray, populate it with machine code and jump the current instruction pointer there.
    :

    No, but that's not how they work (or at least not some of them). You're a C-er, you ought to know better! AFAIK, this can only be done in classes. Basically, a class and it's interface are two different things though VB tries to hide this fact. A class's interface contains the address of all the methods in the class. You basically overwrite that address with the address of your byte array. When you call that method, VB will happily send the execution to that address because we aren't supposed to be able to modify it so it is, of course, still where VB put it. Something along the lines of this I believe (a little hard to recall since I don't use it):

    [code]CopyMemory ByVal ObjPtr(MyObj) + 12, MyFuncArray, 4
    [/code]

    That'd replace the first user-added method with your array.

    Remember, you're not supposed to touch the IP! You're not supposed to play with the vtable either though...
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories