Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Link/C-calling convention ?

Link/C-calling convention ?

Scheduled Pinned Locked Moved C / C++ / MFC
questionworkspace
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 0 Offline
    0 Offline
    0v3rloader
    wrote on last edited by
    #1

    Hello, I have a tricky situation happening in an app which loads a DLL and then tries to retrieve some procedure's addresses. Consider the following code:

    void CDesktopPositionerDlg::OnCapture()
    {
    DFUNC_DEF(CDesktopPositionerDlg::OnCapture);
    BOOL (__stdcall *lpSetup)();
    BOOL bRetVal;
    //!CODE_START--->
    bRetVal = theApp.m_hModule != NULL;
    if(!bRetVal)
    goto loc_ret;
    // inform user
    lpSetup = ::GetProcAddress(theApp.m_hModule, "Setup");
    bRetVal = lpSetup != NULL;
    if(!bRetVal)
    {
    DTRACE(DSTR("Could not retrieve dll function address (err.#%d)", ::GetLastError()));
    goto loc_ret;
    }
    // call function now
    (*lpSetup)();
    .
    :
    .
    // return location
    loc_ret:
    DFUNC_RET2(bRetVal != FALSE, "Mouse hook not setup!", "Mouse hook successfully setup");
    }

    Now notice the call to ::GetProcAddress. If you change the name of the setup function to _Setup@0, which is the name defined in the .LIB file, all is fine and the hook is successfully setup. What I would like to know is the linker option (or C calling convention) I have to adopt in order to prevent such situations from happening. As always, all comments are welcome. David

    A 1 Reply Last reply
    0
    • 0 0v3rloader

      Hello, I have a tricky situation happening in an app which loads a DLL and then tries to retrieve some procedure's addresses. Consider the following code:

      void CDesktopPositionerDlg::OnCapture()
      {
      DFUNC_DEF(CDesktopPositionerDlg::OnCapture);
      BOOL (__stdcall *lpSetup)();
      BOOL bRetVal;
      //!CODE_START--->
      bRetVal = theApp.m_hModule != NULL;
      if(!bRetVal)
      goto loc_ret;
      // inform user
      lpSetup = ::GetProcAddress(theApp.m_hModule, "Setup");
      bRetVal = lpSetup != NULL;
      if(!bRetVal)
      {
      DTRACE(DSTR("Could not retrieve dll function address (err.#%d)", ::GetLastError()));
      goto loc_ret;
      }
      // call function now
      (*lpSetup)();
      .
      :
      .
      // return location
      loc_ret:
      DFUNC_RET2(bRetVal != FALSE, "Mouse hook not setup!", "Mouse hook successfully setup");
      }

      Now notice the call to ::GetProcAddress. If you change the name of the setup function to _Setup@0, which is the name defined in the .LIB file, all is fine and the hook is successfully setup. What I would like to know is the linker option (or C calling convention) I have to adopt in order to prevent such situations from happening. As always, all comments are welcome. David

      A Offline
      A Offline
      Antti Keskinen
      wrote on last edited by
      #2

      I must ask, however inconvinient it sounds, what is the situation you wish to prevent ? Are you, per chance, failing to retrieve the address of the function, unless you name the parameter of GetProcAddress to "_Setup@0" ? How did you export the function from the DLL ? Or was it built by someone else ? Was it built with Visual Studio ? These questions are imperative, mostly because if the last answer is positive, there are two ways of exporting functions from a DLL. If you have access to the DLL code, you should add a __declspec(dllexport) calling convention in front of the setup function. Also, create a module definition file (.DEF) inside the DLL project. Paste the following text into it

      LIBRARY "MyDLL.DLL"
      EXPORTS
      Setup @0

      When you now build the DLL, the GetProcAddress will not fail if you use "Setup" as the function name. Before, you built the DLL using the default settings. In such a case, the exported routines are added with the underscore in front of them. It is called 'behaviour by default' in Microsoft's terms. The only way to remedy it is to use a module definition file. The __declspec definition is added for increased compatibility, as in, fail-safe exporting. Also, if you're using dynamic loading (LoadLibrary), the library file is useless. Library files generated for DLL's are only usable if static linking is used, or if the DLL contains a registered COM component (DirectX applications, for an example). -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.

      0 1 Reply Last reply
      0
      • A Antti Keskinen

        I must ask, however inconvinient it sounds, what is the situation you wish to prevent ? Are you, per chance, failing to retrieve the address of the function, unless you name the parameter of GetProcAddress to "_Setup@0" ? How did you export the function from the DLL ? Or was it built by someone else ? Was it built with Visual Studio ? These questions are imperative, mostly because if the last answer is positive, there are two ways of exporting functions from a DLL. If you have access to the DLL code, you should add a __declspec(dllexport) calling convention in front of the setup function. Also, create a module definition file (.DEF) inside the DLL project. Paste the following text into it

        LIBRARY "MyDLL.DLL"
        EXPORTS
        Setup @0

        When you now build the DLL, the GetProcAddress will not fail if you use "Setup" as the function name. Before, you built the DLL using the default settings. In such a case, the exported routines are added with the underscore in front of them. It is called 'behaviour by default' in Microsoft's terms. The only way to remedy it is to use a module definition file. The __declspec definition is added for increased compatibility, as in, fail-safe exporting. Also, if you're using dynamic loading (LoadLibrary), the library file is useless. Library files generated for DLL's are only usable if static linking is used, or if the DLL contains a registered COM component (DirectX applications, for an example). -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.

        0 Offline
        0 Offline
        0v3rloader
        wrote on last edited by
        #3

        Hi Antti and thanks for the reply. :) Antti Keskinen wrote: Are you, per chance, failing to retrieve the address of the function, unless you name the parameter of GetProcAddress to "_Setup@0" ? That's it basically. After having finished the DLL I tried to access some of its functions in my MFC App by calling GetProcAddress and passing the names of the functions. It didn't work. Well it happens that, after taking a look at the .MAP file, all the functions are added the underscores and also some additional characters. Therefore, trying to retrieve Setup's proc address from the Dll would only work if I called GetProcAddress passing _Setup@0. I don't really know the workarounds one has/can do in order to prevent this from happening. I mean, how can I export the function as is, making it accessible by its true name? Will I have to create a definition file for the Dll? Again, thanks for the reply. By the way, I am using the __declspec(dllexport) calling convention.

        A 1 Reply Last reply
        0
        • 0 0v3rloader

          Hi Antti and thanks for the reply. :) Antti Keskinen wrote: Are you, per chance, failing to retrieve the address of the function, unless you name the parameter of GetProcAddress to "_Setup@0" ? That's it basically. After having finished the DLL I tried to access some of its functions in my MFC App by calling GetProcAddress and passing the names of the functions. It didn't work. Well it happens that, after taking a look at the .MAP file, all the functions are added the underscores and also some additional characters. Therefore, trying to retrieve Setup's proc address from the Dll would only work if I called GetProcAddress passing _Setup@0. I don't really know the workarounds one has/can do in order to prevent this from happening. I mean, how can I export the function as is, making it accessible by its true name? Will I have to create a definition file for the Dll? Again, thanks for the reply. By the way, I am using the __declspec(dllexport) calling convention.

          A Offline
          A Offline
          Antti Keskinen
          wrote on last edited by
          #4

          If you want to be sure by what name a function is exported, use a module definition file and rebuild the DLL. For example:

          // In DLL code, somewhere
          __declspec(dllexport) int Setup(void);

          // The module definition file
          LIBRARY "MyDLL.DLL"

          EXPORTS
          Setup @1

          This would export the Setup function from the DLL with it's true name, and GetProcAddress will not fail if you ask it to look for a function called "Setup". Also, using both the __declspec and the definition file is just about making sure it works. It will not get exported twice. Also, you can rename the exported symbols in the module definition file. Assuming that Setup is still the function name inside the DLL you wish to export, the following statement under EXPORTS would rename this symbol:

          Exported1 = Setup @1

          Now, requesting "Exported1" with GetProcAddress would return the address of "Setup". However, asking for "Setup" would return an error. Basically, the difference on which one to use depends on if you want a library file (.LIB) or not. The __declspec(dllexport) adds an entry to the library file, so that if you link with this library file, you can call the exported functions, and the DLL will be loaded and the function executed (static linking). However, if you use dynamic (run-time) loading, the module definition file is the only way to specify the names of the exported functions explicitly. It is not possible to use a library file with dynamic loading. This will not work, it is just not designed to work that way. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.

          0 1 Reply Last reply
          0
          • A Antti Keskinen

            If you want to be sure by what name a function is exported, use a module definition file and rebuild the DLL. For example:

            // In DLL code, somewhere
            __declspec(dllexport) int Setup(void);

            // The module definition file
            LIBRARY "MyDLL.DLL"

            EXPORTS
            Setup @1

            This would export the Setup function from the DLL with it's true name, and GetProcAddress will not fail if you ask it to look for a function called "Setup". Also, using both the __declspec and the definition file is just about making sure it works. It will not get exported twice. Also, you can rename the exported symbols in the module definition file. Assuming that Setup is still the function name inside the DLL you wish to export, the following statement under EXPORTS would rename this symbol:

            Exported1 = Setup @1

            Now, requesting "Exported1" with GetProcAddress would return the address of "Setup". However, asking for "Setup" would return an error. Basically, the difference on which one to use depends on if you want a library file (.LIB) or not. The __declspec(dllexport) adds an entry to the library file, so that if you link with this library file, you can call the exported functions, and the DLL will be loaded and the function executed (static linking). However, if you use dynamic (run-time) loading, the module definition file is the only way to specify the names of the exported functions explicitly. It is not possible to use a library file with dynamic loading. This will not work, it is just not designed to work that way. -Antti Keskinen ---------------------------------------------- The definition of impossible is strictly dependant on what we think is possible.

            0 Offline
            0 Offline
            0v3rloader
            wrote on last edited by
            #5

            Great stuff Antti! That is exactly what I was looking for! Thanks a lot for the invaluable feedback, Antti. - David

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups