C++ Visual Studio Windows:如何在 dll 中声明但不定义外部函数
Posted
技术标签:
【中文标题】C++ Visual Studio Windows:如何在 dll 中声明但不定义外部函数【英文标题】:C++ Visual Studio Windows: how to declare but not define extern function in dll 【发布时间】:2020-10-14 19:28:01 【问题描述】:我有一个项目编译成库,并声明了某个函数要由库的用户实现:
//To be defined by user
Application* CreateApplication();
在 Linux 上将代码编译到共享库中时,它可以完美运行。库的任何用户都可以为声明的函数定义一个实现,并且可以在库中使用它。如果库的用户忘记定义一个实现,他们会得到一个错误指出这一点。
我现在正在将库移植到 Windows,它应该被编译成 dll。但是,由于 Visual Studio 使用的链接器在抱怨,我遇到了问题:
unresolved external symbol Application* __cdecl CreateApplication(void)
我尝试添加 extern 关键字来表明函数的定义在其他地方,但这不起作用。
为什么我不能像这样在 dll 中声明(但不定义)函数?我应该如何修复我的代码,使其在 Linux 和 Windows 上都能正常工作?
【问题讨论】:
如果您在 Linux 中这样做并在共享库上使用dlopen
+ dlsym
,除非您之前已加载用户的库,否则您将收到运行时错误。 "函数dlsym()
接受由dlopen(3)
返回的动态加载共享对象的“句柄”以及以空结尾的符号名称,并返回该符号被加载到内存中的地址。如果符号是未找到,在指定对象或由dlopen(3)
在加载该对象时自动加载的任何共享对象中,dlsym()
返回NULL
。"
我正在同一个项目中编译库的用户。也许这就是它起作用的原因?也许问题应该是我应该如何在 Windows 和 Linux 中做到这一点?
是的,这听起来很脆弱。
对我应该如何处理这个问题有什么建议吗?将其设为静态库会解决问题吗?
.... 或按照 Remy 的建议进行操作 :-)
【参考方案1】:
你试图做的只能在静态库中工作,它不能在像 DLL 这样的动态库中工作。为此,您必须更改代码以改用函数指针。使用 DLL 的应用程序可以从自己的代码中传递所需函数的地址,然后 DLL 可以将该地址分配给它根据需要使用的变量,例如:
标题:
#ifndef MYLIB_H
#ifndef MYLIB_H
#ifdef COMPILING_MY_LIB
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT __declspec(dllimport)
#endif
// declare Application as needed...
typedef Application (*lpCreateApplicationFunc)();
#ifdef __cplusplus
extern "C"
#endif
MY_EXPORT void SetCreateApplicationFunc(lpCreateApplicationFunc func);
#ifdef __cplusplus
#endif
#endif
DLL:
#define COMPILING_MY_LIB
#include "MyLib.h"
//To be defined by user
lpCreateApplicationFunc CreateApplication = NULL;
void SetCreateApplicationFunc(lpCreateApplicationFunc func)
CreateApplication = func;
void doSomething()
Application *app = NULL;
if (CreateApplication)
app = (*CreateApplication)();
if (app)
...
EXE:
#include "MyLib.h"
Application MyCreateApplicationFunc()
...
// during startup, call this...
SetCreateApplicationFunc(&MyCreateApplicationFunc);
【讨论】:
以上是关于C++ Visual Studio Windows:如何在 dll 中声明但不定义外部函数的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Windows 桌面 (C++) 打开 Visual Studio Express 2013? [关闭]
将 C++ Win32 控制台项目类集成到 Visual Studio 2008 中的 Visual C++(Windows 窗体应用程序)项目中
如何在 Visual Studio 2017 中创建 C++ Windows 桌面应用程序?
在 Windows 上安装 OpenCV 并使用 Visual Studio C++ 构建程序