如何在运行时将DLL链接到exe文件?

时间:2014-07-21 05:04:57

标签: c dll runtime.exec

我是编程新手,我创建了一个dll项目,我将只打印一行。在应用程序项目中,我调用了dll项目中定义的函数。

我的问题是,我在构建dll项目后不久就收到了dll文件。但是当我构建主应用程序时,即应用程序项目时,我收到以下错误。

--------------------Configuration: test_bench - Win32 Debug-------------------- 
Compiling...
main.c
Linking...
main.obj : error LNK2001: unresolved external symbol _print_dll
../../exec/test_bench.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

test_bench.exe - 2 error(s), 0 warning(s)

如果我在构建之前链接obj,它就会被构建。但是,如果我更改了dll项目的代码,我必须重新构建主项目,这在运行dll时不应该是必需的。

请帮我实现这个目标

3 个答案:

答案 0 :(得分:0)

此错误表示您没有链接可执行文件中的库(DLL),这就是它无法找到函数print_dll的原因。

您可以通过LoadLibray()

在Windows中动态加载库

以下是有关如何执行此操作的示例:http://msdn.microsoft.com/en-us/library/windows/desktop/ms686944(v=vs.85).aspx

答案 1 :(得分:0)

要在运行时链接dll项目,您需要在main文件中实现运行时链接。如果实现运行时链接方式,则无需每次都重新构建项目。  对于运行时链接,您需要以下功能

#include <dlfcn.h>

   void *dlopen(const char *filename, int flag);

   char *dlerror(void);

   void *dlsym(void *handle, const char *symbol); //symbol is your function name

   int dlclose(void *handle);

   Link with -ldl.

有关详细信息,请参见手册页。 但在更改代码时,如果更改了函数名称,则应在symbol处使用相同的名称。

答案 2 :(得分:0)

我写了一个小二进制模板来帮助dlopen相关的调用。您需要针对特定​​用例进行调整(因为它只处理字符串),但我发现它在很多场合都很方便。

用法:dlopener /path/to/library.extension function_name [args...]

//gcc -rdynamic -o dlopener dlopener.c -ldl
#include <dlfcn.h> /*for dlopen,dlsym,dlclose*/

int main(int argc, char **argv){

   /* get a "handle" for a shared library*/
   void *handle = dlopen(argv[1], RTLD_LAZY);

   /* make sure we got a handle before continuing*/
   if (! handle) return 1;

   /*undefined, but workable solution : POSIX.1-2003 (Technical Corrigendum 1) */
   void* (*f)()=dlsym(handle, argv[2]);

   /*now call the function f(argv[3],argv[4],...argv[argc]); */
   //TODO convert args to unsigned char representations for other types 
   while (argc > 2)  /*ugh, have to use asm to preserve stack*/
      asm("push %0"::"r"(argv[argc--])); /*from right to left*/

   asm("call *%0"::"r"(f)); //TODO  "=a"(ret) where is uchar[XXX]

   /*remember that shared library we opened?*/
   dlclose(handle);

   return 0;
}

注意:对于某些WIN32函数(cdecl调用约定IIRC),您需要使用与push不同的asm机制来获取寄存器而不是堆栈中的值