我有一个.lib库,它提供的API具有全局变量,例如文件/设备句柄,这些API将通过与.lib静态链接而由application(.exe)使用。该应用程序使用.lib提供的API进行一些初始化(例如打开设备/文件等),并在运行时加载.dll以使用.lib提供的API执行对设备/文件的写入和读取操作。问题是,当我将静态库与.exe和.dll链接时,它们具有不同的库副本,并且在运行时打开.dll时,应用程序完成的初始化未保留(因为.dll和.exe似乎正在使用自己的.lib副本)。当我制作.dll而不是静态库并导出所有API并将其导入.exe和.dll时,此问题得以解决。
但是我想使.exe独立运行,没有任何.dll依赖项,运行时.dll除外。
这是方案的示例代码
main.c(.exe)
#include <stdio.h>
#include <windows.h>
#include "static_lib.h"
typedef void (*FNPTR)(void);
FNPTR functionname;
int main(){
HINSTANCE hLib;
LPTSTR dllname = "dynamic.dll";
hLib=LoadLibrary(dllname);
if(hLib==NULL)
{
printf("Unable to load dll %s\n", dllname);
return 0;
}
functionname=(FNPTR)GetProcAddress((HMODULE)hLib, (LPCSTR)"dyn_main");
if((functionname==NULL))
{
printf("unable to load test function %s\n", dllname);
FreeLibrary((HMODULE)hLib);
return 0;
}
printf("Var in main: ");
test_func();
printf("calling dyn_main:");
functionname();
printf("back to main:");
printvar();
FreeLibrary((HMODULE)hLib);
return 1;
}
static_lib.c(静态库)
#include <stdio.h>
#include <windows.h>
#include "static_lib.h"
int var; //can be file or device handle
int test_func(){ //initializes the device
change_var();
printvar();
return 1;
}
void printvar(void){ //write/read device/file
printf("%d\n",var);
return;
}
void change_var(void){ //opens device/file
var = 1;
return;
}
static_lib.h
#ifndef _STATIC_LIB_H_
#define _STATIC_LIB_H_
#if defined (DLL_EXPORT)
#define DLL_IMPORT_EXPORT __declspec(dllexport)
#else
#define DLL_IMPORT_EXPORT __declspec(dllimport)
#endif
DLL_IMPORT_EXPORT void change_var(void);
DLL_IMPORT_EXPORT void printvar(void);
DLL_IMPORT_EXPORT int test_func();
#endif
dynamic.c(.dll)
#include <stdio.h>
#include <windows.h>
#include "static_lib.h"
__declspec(dllexport) void dyn_main(void){
printvar(); //uses the device
return;
}
使用动态链接进行编译的命令行为
cl /c /nologo main.c dynamic.c
cl /c /nologo /DDLL_EXPORT static_lib.c
LINK /nologo /DLL static_lib.obj
LINK /nologo /DLL dynamic.obj static_lib.lib
LINK /nologo main.obj static_lib.lib
输出为:
main.exe
Var in main: 1
calling dyn_main:1
back to main:1
但是当我创建一个静态库并与.exe和.dll链接
cl /c /nologo main.c dynamic.c static_lib.c
LIB static_lib.obj
LINK /nologo /DLL dynamic.obj static_lib.lib
LINK /nologo main.obj static_lib.lib
输出为
main.exe
Var in main: 1
calling dyn_main:0
back to main:1
在实际情况下,该程序由于.dll中无效的设备/文件句柄而崩溃。
总有没有将API从.exe导出到.dll的过程,而没有链接器给出未解决的符号错误并且仅维护.dll和.exe使用的静态库副本的情况?
我已经搜索了问题,发现了这个问题:Dynamic Loading of my DLL with Static Lib in Windows Environment
它表示我们无法在Windows环境中执行此操作。但是我想先确定一下其他选择。