在.dll(运行时加载)和.exe

时间:2018-08-03 08:21:17

标签: windows visual-c++ dll static-linking dynamic-linking

我有一个.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环境中执行此操作。但是我想先确定一下其他选择。

0 个答案:

没有答案
相关问题