【问题标题】:share global variable: interaction between main, lib.a and dll共享全局变量:main、lib.a 和 dll 之间的交互
【发布时间】:2015-08-14 18:24:18
【问题描述】:

我保留了必需品。

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

模块.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

调用者.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

【问题讨论】:

  • 我相信你在内存中有两个不同的地方,名为global。一个在调用者中,因为您使用 lcommon 对其进行了静态编译。通过set_ptr 在那里设置数据。第二个是在module 空间中(出于相同的原因),但您从未在那里调用set_ptr()。在dll_initmain 中检查global 的内存地址。如果它们不相同,则需要在 `dll_init` 中调用 set_ptr

标签: c dll hyperlink static-libraries


【解决方案1】:

我相信您在内存中有 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

欢迎提出其他建议

【讨论】:

    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 2012-12-14
    • 1970-01-01
    相关资源
    最近更新 更多