如何在DLL中调用一个函数定义另一个项目

时间:2017-02-13 09:28:16

标签: c++ dll

我想在DLL中调用一个函数(假设在X项目中定义了foo函数)。因此DLL永远不会知道这个foo函数的确切实现。但后来我想在X项目中使用这个DLL(包含foo函数)。 当我尝试编译DLL时,链接器会给出" Unresolved external"错误。如何告诉编译器foo函数是在另一个项目中定义的。 例如;

DLL项目中的

foo.cpp

extern void foo();
void DLLFunction()
{
    foo();
}

X项目中的impl.cpp

void foo()
{
    //Do something
}

如果我可以在DLL项目中编译foo.cpp,我将在X Project中使用这个DLL。

3 个答案:

答案 0 :(得分:0)

你可以做的是代替编写extern,你可以动态加载DLL

e.g。

auto hd = LoadLibrary("YourDll.DLL");
typedef void(*userfunc)() ;
userfunc p = GetProcAddress(hd, "foo");
p();

替代。链接到构建DLL时创建的.lib文件

discalimer:清除代码,错误检查等。

答案 1 :(得分:0)

如果您使用的是最新版本的Visual Studio IDE,则只需引用它即可 - Visual Studio将负责其余部分。为此,右键单击解决方案资源管理器中的“引用”条目,以获取要链接到DLL的项目。从那里,选择解决方案中的其他DLL项目:

enter image description here enter image description here 这将处理所需的所有链接,如果您重命名项目或更改输出文件的名称,则可以省去更改项目设置的麻烦。

如果您的解决方案中没有其他项目,则必须坚持使用常规静态链接过程:

  • 项目设置 - >链接器 - >一般 - >其他图书馆馆藏
  • 项目设置 - >链接器 - >输入 - >附加依赖

如果要在运行时动态链接DLL,可以使用Andreas K描述的方法。

答案 2 :(得分:0)

如果我正确理解了这个问题,你想要一个DLL,它从链接的可执行文件中导入一个函数。

一般情况下这是可能的,但是很棘手,所以首先要考虑的是你是否真的需要这样做,或者你是否可以将DLL功能改为例如接受一个函数指针(然后不需要将符号从可执行文件导入DLL)。

仍然可以在DLL中使用来自可执行文件的符号。可以从可执行文件中导出符号(函数)并在DLL中使用(通常与从DLL导出的方式相同,例如Windows上的“__declspec(dllexport)”)。然而,棘手的部分是,默认情况下,您需要依赖项链接特定对象,即在这种情况下,您需要DLL链接可执行文件和可执行文件以链接DLL,这是一个循环依赖。

所以你需要打破循环依赖。有一些可能性:

  1. 动态加载DLL作为插件 - 在Windows上的Posix和LoadLibrary()上使用dlopen()。然后你不需要DLL来构建可执行文件,你可以链接提供符号的EXE和DLL。

  2. 反过来 - 在Windows上,您可以将导出的符号从可执行文件动态导入DLL(GetModuleHandle()GetProcAddress())。

  3. 允许使用未解析的符号构建DLL。然后使用未解析的符号构建DLL,并针对DLL构建EXE。执行时,可执行文件将加载DLL并提供符号。

  4. 允许使用未解析的符号构建DLL: 在Linux GCC中,这是默认行为(共享对象不强制执行要解析的符号),除非使用“-Wl, - no-undefined”构建。

    在Windows MSVC中,通过向链接器提供“/FORCE:UNRESOLVED”参数,可以在构建DLL时忽略未解析的符号。请注意,在Windows / MSVC上,在生成EXE .lib文件之后,需要再次针对该文件重建DLL以导入符号。