Thread: Pointer to function parsing in VC++

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    10

    Pointer to function parsing in VC++

    Oi!

    I've made my own programming language using C++ as the base for it (All code for the interpreter is in C++ and the Dev-API is in C++).

    Now for my next version I've made a Dynamic Linker for it written in C++, which will let my language to open up Shared libraries like *.so and *.dll files.

    Here's my problem. Since I can't predict before hand how the function pointer should be since my language is compiled at run time. So my Dynamic Linker has to have a "unified" pointer. Well I have one for each return type. The argument list is the tricky one. And I could solve this in GCC by turning the pointer to this:

    Code:
    typedef long ArgType;
    #define ARGLIST \      /* Sets twenty ArgType after each other like an argument list with up to twenty arguments */
    ArgType, ArgType, ArgType, ArgType, \
    ArgType, ArgType, ArgType, ArgType, \
    ArgType, ArgType, ArgType, ArgType, \
    ArgType, ArgType, ArgType, ArgType, \
    ArgType, ArgType, ArgType, ArgType \
    
    #define ARGSTACK(stack) \      /* The same as before but with stack[0] instead up to twenty */
    stack[0], stack[1], stack[2], stack[3], \
    stack[4], stack[5], stack[6], stack[7], \
    stack[8], stack[9], stack[10], stack[11], \
    stack[12], stack[13], stack[14], stack[15], \
    stack[16], stack[17], stack[18], stack[19] \
    // More code
    
    <type> (*pointerParsed)(ARGLIST) = (<type> (*)(ARGLIST) pointerToFunctionInMemory;
    pointerParsed(ARGSTACK(argStack)); // Call the function, argStack is an array of twenty with long values for arguments.
    This works for GCC. But in VC++ I get a problem. The function pointerParsed points at is called (for instance I opened kernel32.dll and used Sleep(5000) and it sleept for 5 second) but when it returns everything crashes down. And I get an exception from Visual Studio which tells me that this happen when I call a function with a pointer that has a different calling convention. I need a solution for that. But I'm a Linux developer and not that familiar with VC++. I haven't been capable of coming up with anything that fixes this.

    I know this is not part of standard C++ or anything like that. I got criticism when asking for help in an IRC channel telling me I was a moron and idiot because they thought it was broken. Ruby's Dynamic Linker (written in C) uses the same thing as me. Though I couldn't find how they solved it with VC++. Or maybe it can't be compiled by VC++ simply.
    Last edited by Groogy; 04-26-2009 at 06:24 AM.

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by Groogy View Post
    And I get an exception from Visual Studio which tells me that this happen when I call a function with a pointer that has a different calling convention.
    Windows API functions have __stdcall calling conventions - this it what you are missing I think

    Take a look: Calling Conventions (C++)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Aug 2007
    Posts
    10
    Quote Originally Posted by vart View Post
    Windows API functions have __stdcall calling conventions - this it what you are missing I think

    Take a look: Calling Conventions (C++)
    Sorry none of those worked. __fastcall though didn't generate an error. It only didn't bother to respond back with a return value :P

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Could it be that you are casting a pointer to function into a pointer to function with a different signature (one that takes 20 longs and returns ?), and calling the function through such pointer might be undefined behavior?

    At least one needs reinterpret_cast for such cast (which shows you really have to know what you are doing if you want to use the casted pointer), and not for example a static_cast (which would mean that it is pretty much OK to use the result).

    Code:
    int foo()
    {
        return 1;
    };
    
    int main()
    {
        typedef int(*MyFun)(long, long);
        MyFun fun = reinterpret_cast<MyFun>(&foo);
        fun(0, 0);
    }
    Last edited by anon; 04-26-2009 at 08:34 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Aug 2007
    Posts
    10
    Quote Originally Posted by anon View Post
    Could it be that you are casting a pointer to function into a pointer to function with a different signature (one that takes 20 longs and returns ?), and calling the function through such pointer might be undefined behavior?

    At least one needs reinterpret_cast for such cast (which shows you really have to know what you are doing if you want to use the casted pointer), and not for example a static_cast (which would mean that it is pretty much OK to use the result).

    Code:
    int foo()
    {
        return 1;
    };
    
    int main()
    {
        typedef int(*MyFun)(long, long);
        MyFun fun = reinterpret_cast<MyFun>(&foo);
        fun(0, 0);
    }
    Yeah it's because of that. But I have no idea of how to fix it other than to manually make each variation of the twenty arguments. As noted before, GCC let's me do it like how I have it now. But VC++ doesn't.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    10
    Aight, I think I managed to fix it so it works. I have a macro (inspired from Ruby) that let's me easily recreate the different argument lengths. And it works when using __stdcall. But since there is different call conventions for VC++. How do I know to use which when?

    Why can't windows keep it as simple as Linux?

    ** EDIT **
    Realised that __stdcall only applies to WinAPI functions. But how do I know if a function is a WinAPI function? Can I test towards some function in the WinAPI or do I have to keep an internal list of the function symbols?
    Last edited by Groogy; 04-26-2009 at 02:00 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  3. Function Pointer help
    By Skydt in forum C Programming
    Replies: 5
    Last Post: 12-02-2005, 09:13 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. Glib and file manipulation
    By unixOZ in forum Linux Programming
    Replies: 1
    Last Post: 03-22-2004, 09:39 PM