I have a .lib library which provides APIs which have global variables like file/device handles, these APIs are going to be used by the application(.exe) by linking with .lib statically. The application does some initialization using APIs provided by .lib (like opening device/file etc) and loads the .dll during run time to perform writes and reads to the device/file using APIs provided by .lib. The problem is when I link the static library with both .exe and .dll they have different copies of libraries and the initialization done by the application is not retained when .dll is opened during run-time (since .dll and .exe seem to be working with their own copy of .lib). This problem is solved when I make .dll instead of static library and export all APIs and import them in .exe and .dll.
But I want to make the .exe standalone without any .dll dependencies except for run-time .dll .
Here is sample code for scenario
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 (static library)
#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;
}
The command line for compiling with dynamic linking is
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
The output is:
main.exe
Var in main: 1
calling dyn_main:1
back to main:1
But when I make a static library and link with .exe and .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
The output is
main.exe
Var in main: 1
calling dyn_main:0
back to main:1
And in real scenario the program crashes as it is invalid device/file handle inside .dll.
Is there anyway to export APIs into .dll from .exe without linker giving unresolved symbol error and maintaining only one copy of static library used by .dll and .exe?
I have searched for the problem and I found this: Dynamic Loading of my DLL with Static Lib in Windows Environment
It says we cannot do this in windows environment. But I want to make sure before thinking of other alternatives.