Exporting a function, cast into a pointer through

2019-09-10 03:46发布

This is an elaboration to an earlier question: How to reset state machines when unit testing C
There is also a similar question but i don't the answer match my problem and i have some examples i wish to present: Exporting a function pointer from dll

I have two sets of code that i expect should do the same but the latter crashes. Using mingw32 and Win7.

The function to be exported. This is to be considered legacy and unmutable.
addxy.c

    int addXY(int x, int y)
    {
      return x + y;
    }    

addxy.h

    int addXY(int x, int y);

The working example

main.c

    #include <stdio.h>
    #include "addxy.h"

    typedef int (__cdecl *addXYWrap_t)(int a, int b);

    addXYWrap_t addXYWrap = (addXYWrap_t)addXY;

    void main()
    {
      printf("result: %d", addXYWrap(3, 4));
    }

Yielding

result: 7

The crashing example

addxydll.c

    #include <stdio.h>
    #include "addxy.h"

    typedef int (__cdecl *addXYWrap_t)(int a, int b);

    __declspec(dllexport) addXYWrap_t addXYWrap = (addXYWrap_t)addXY;

main.c

    #include <windows.h>
    #include <stdio.h>

    typedef int (__cdecl *func)(int a, int b);

    void main()
    {
      HINSTANCE loadedDLL = LoadLibrary("addxy.dll");

      if(!loadedDLL) {
        printf("DLL not loaded");
        return;
      } else {
        printf("DLL loaded\n");
      }

      func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");

      if(!addition) {
        printf("Func not loaded");
        return;
      } else {
        printf("Func loaded\n");
      }

      printf("result: %d", addition(3, 4));
    }

Yielding

DLL loaded
Func loaded

before it chrashes.

The crash gives no information as to why or what.
Is it a syntactical error or conceptional one?

3条回答
爷的心禁止访问
2楼-- · 2019-09-10 04:29
func addition = (func)GetProcAddress(loadedDLL, "addXYWrap");

This call to GetProcAddress returns the address of addXYWrap, not its value. Since addXYWrap is a function pointer (of the same type as func), that means it returns a pointer to a function pointer, or a func*.

Try changing that line to this:

func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");

 

Or, alternatively:

func* addition = (func*)GetProcAddress(loadedDLL, "addXYWrap");

and then (*addition)(3, 4)

查看更多
戒情不戒烟
3楼-- · 2019-09-10 04:40
int addXY(int x, int y)
{
  return x + y;
}
__declspec(dllexport) addXYWrap_t addXYWrap = (addXYWrap_t)addXY;

This is an error. You have to export function, not a global pointer. That is,

/* addxy.c */
__declspec(dllexport) int addXY(int x, int y)
{
  return x + y;
}
....
/* main.c */
func addition = (func)GetProcAddress(loadedDLL, "_addXY");
查看更多
放荡不羁爱自由
4楼-- · 2019-09-10 04:41

So, based on comments above, you appear to be overthinking it. If you did need a function pointer, then to correctly call it, you must first dereference GetProcAddress like so:

func addition = *(func*)GetProcAddress(loadedDLL, "addXYWrap");

However, a much more convenient solution is to just wrap the function:

__declspec(dllexport) int myAddXY(int x, int y)
{
    return addXY(x, y);
}
查看更多
登录 后发表回答