共享全局变量:main,lib.a和dll之间的交互

时间:2015-08-14 18:24:19

标签: c dll hyperlink static-libraries

我保留了必需品。

caller.exe加载dll,然后调用dll中声明的函数dll_init。

这最后一个函数调用函数" get_ptr"在公共库中声明,它应该返回一个指向全局变量的指针。

问题是:

  • 每当caller.exe调用" get_ptr"它返回一个有效的指针,该指针与之前在caller.exe上分配的指针相同。
  • 每当dll通过它起作用" dll_init" (在拜访之后) caller.exe)调用" get_ptr" (知道dll链接到 static lib)它返回NULL指针。

我缺少什么?

libcommon.c

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
/***************header****************/
int *get_ptr(void);
int set_ptr(void);
/**********************************/

int *global=NULL;
//extern __declspec(dllimport) int *global; doesnt work

int set_ptr() {
    global = (int *) malloc(sizeof(int));
    printf("global allocated to %p\n",global);
    *global=485; //random value
    return 0;
}

int *get_ptr() {
    return global;
}

这里是编译命令(makefile简化):

gcc.exe -c libcommon.c -o libcommon.o -m32
ar r libcommon.a libcommon.o
ranlib libcommon.a

的module.c

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

#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif

DLLIMPORT int dll_init(void) {
    int *ptr=(int *) get_ptr();

    puts("dll run");
    printf("from dll global: %p\n",ptr);
    puts("dll end");

    return 0;
}

编译:

gcc.exe -c module.c -o module.o -m32 -DBUILDING_DLL=1
gcc.exe -shared module.o -o module.dll -static-libgcc -lws2_32 -m32 -s -L"." -lcommon -Wl,--output-def,libmodule.def,--out-implib,libmodule.a,--add-stdcall-alias

caller.c

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

typedef void(voidfunc)(void);
voidfunc *fct_ptr;

int test(int a) {
printf("%d",a++);
}

int main() {
    set_ptr();
    printf("::%p\n",get_ptr());

    /* Load the dll then call dll_init */
    HMODULE dllptr = LoadLibrary("module.dll");
    if (dllptr != NULL) {
        fct_ptr = (voidfunc *) GetProcAddress(dllptr, "dll_init");
        puts("loaded");
        if (fct_ptr != NULL)
           fct_ptr();
        FreeLibrary(dllptr);
    }
}

编译:

gcc.exe caller.c -o caller.exe -m32 -static-libgcc -lws2_32 -L. -lcommon -m32

1 个答案:

答案 0 :(得分:0)

  

我相信你在内存中有2个不同的名字叫做global。一个是   在调用程序中,因为您使用lcommon静态编译它。数据已设定   那里通过set_ptr。第二是模块空间(出于同样的原因),   但你从来没有在那里调用过set_ptr()。检查全局的内存地址   在dll_init和main中。如果它们不相同,那么你需要   在你的'dll_init``

中调用set_ptr

他是对的,我认为与exe和dll链接的常见静态库是错误的想法。 解决方案在这里:.dll Plugin that uses functions defined in the main executable

欢迎任何其他建议