我是编程新手,我创建了一个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时不应该是必需的。
请帮我实现这个目标
答案 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机制来获取寄存器而不是堆栈中的值