共享全局变量:main、lib.a 和 dll 之间的交互
share global variable: interaction between main, lib.a and dll
我保留了必要的。
caller.exe加载dll,然后调用dll中声明的函数dll_init。
最后一个函数调用在公共库中声明的函数 "get_ptr",它应该 return 一个指向全局变量的指针。
问题是:
- 每当 caller.exe 调用 "get_ptr" 时,它 return 是一个有效的指针,与之前在 caller.exe 上分配的指针相同。
- 只要通过它的 dll 函数 "dll_init"(在被调用之后
caller.exe) 调用 "get_ptr"(知道 dll 链接到
静态库)它 return 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
I believe you have 2 different places in memory named global. One is
in caller since you compiled it statically with lcommon. Data is set
there via set_ptr. Second is in module space (for the same reasons),
but you never called set_ptr() there. Check memory address of global
inside dll_init and in main. If they are not the same, you then need
to call set_ptr in your `dll_init``
他是对的,我认为用 exe 和 dll 链接的公共静态库是一个错误的想法。
解决方案在这里:.dll Plugin that uses functions defined in the main executable
欢迎提出任何其他建议
我保留了必要的。
caller.exe加载dll,然后调用dll中声明的函数dll_init。
最后一个函数调用在公共库中声明的函数 "get_ptr",它应该 return 一个指向全局变量的指针。
问题是:
- 每当 caller.exe 调用 "get_ptr" 时,它 return 是一个有效的指针,与之前在 caller.exe 上分配的指针相同。
- 只要通过它的 dll 函数 "dll_init"(在被调用之后 caller.exe) 调用 "get_ptr"(知道 dll 链接到 静态库)它 return 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
I believe you have 2 different places in memory named global. One is in caller since you compiled it statically with lcommon. Data is set there via set_ptr. Second is in module space (for the same reasons), but you never called set_ptr() there. Check memory address of global inside dll_init and in main. If they are not the same, you then need to call set_ptr in your `dll_init``
他是对的,我认为用 exe 和 dll 链接的公共静态库是一个错误的想法。 解决方案在这里:.dll Plugin that uses functions defined in the main executable
欢迎提出任何其他建议