使用 dllexport 从 DLL 导出函数

2024-01-04

我想要一个从 C++ Windows DLL 导出函数的简单示例。

我想看看标题.cpp文件,以及.def文件(如果绝对需要)。

我希望导出的名称是未装饰的。我想使用最标准的调用约定(__stdcall?)。我想要使​​用__declspec(dllexport)并且不必使用.def file.

例如:

  //header
  extern "C"
  {
   __declspec(dllexport) int __stdcall foo(long bar);
  }

  //cpp
  int __stdcall foo(long bar)
  {
    return 0;
  }

我试图避免链接器在名称中添加下划线和/或数字(字节数?)。

我不支持也没关系dllimport and dllexport使用相同的标头。我不需要任何有关导出 C++ 类方法的信息,只需要 C 风格的全局函数。

UPDATE

不包括调用约定(并使用extern "C") 为我提供了我喜欢的导出名称,但这是什么意思?我得到的默认调用约定是什么 pinvoke (.NET)、声明 (vb6) 和GetProcAddress会期望吗? (我猜对于GetProcAddress这取决于调用者创建的函数指针)。

我希望这个 DLL 在没有头文件的情况下使用,所以我真的不需要很多花哨的东西#defines使标头可供调用者使用。

我同意的答案是我必须使用*.def file.


如果您想要纯 C 导出,请使用 C 项目而不是 C++。 C++ DLL 依赖于所有 C++ 体系(命名空间等)的名称修改。您可以通过进入 C/C++->Advanced 下的项目设置将代码编译为 C,其中有一个选项“Compile As”对应于编译器开关 /TP 和 /TC。

如果您仍然想使用 C++ 编写 lib 的内部结构,但导出一些未损坏的函数以便在 C++ 外部使用,请参阅下面的第二部分。

在 VC++ 中导出/导入 DLL 库

您真正想要做的是在标头中定义一个条件宏,该标头将包含在 DLL 项目的所有源文件中:

#ifdef LIBRARY_EXPORTS
#    define LIBRARY_API __declspec(dllexport)
#else
#    define LIBRARY_API __declspec(dllimport)
#endif

然后在您想要导出的函数上使用LIBRARY_API:

LIBRARY_API int GetCoolInteger();

在您的库构建项目中创建一个定义LIBRARY_EXPORTS这将导致您的函数被导出以用于您的 DLL 构建。

Since LIBRARY_EXPORTS不会在使用 DLL 的项目中定义,当该项目包含库的头文件时,所有函数都将被导入。

如果你的库是跨平台的,你可以在不在 Windows 上时将 LIBRARY_API 定义为空:

#ifdef _WIN32
#    ifdef LIBRARY_EXPORTS
#        define LIBRARY_API __declspec(dllexport)
#    else
#        define LIBRARY_API __declspec(dllimport)
#    endif
#elif
#    define LIBRARY_API
#endif

使用 dllexport/dllimport 时不需要使用 DEF 文件,如果使用 DEF 文件则不需要使用 dllexport/dllimport。这两种方法以不同的方式完成相同的任务,我相信 dllexport/dllimport 是这两种方法中推荐的方法。

从 LoadLibrary/PInvoke 的 C++ DLL 导出未损坏的函数

如果您需要使用 LoadLibrary 和 GetProcAddress,或者可能从其他语言导入(即来自 .NET 的 PInvoke,或 Python/R 中的 FFI 等),您可以使用extern "C"与您的 dllexport 内联,告诉 C++ 编译器不要破坏名称。由于我们使用 GetProcAddress 而不是 dllimport,因此我们不需要从上面进行 ifdef 舞蹈,只需一个简单的 dllexport:

代码:

#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)

EXTERN_DLL_EXPORT int getEngineVersion() {
  return 1;
}

EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
  K.getGraphicsServer().addGraphicsDriver(
    auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
  );
}

这是使用 Dumpbin /exports 导出的内容:

  Dump of file opengl_plugin.dll

  File Type: DLL

  Section contains the following exports for opengl_plugin.dll

    00000000 characteristics
    49866068 time date stamp Sun Feb 01 19:54:32 2009
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 0001110E getEngineVersion = @ILT+265(_getEngineVersion)
          2    1 00011028 registerPlugin = @ILT+35(_registerPlugin)

所以这段代码工作正常:

m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");

m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
  ::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
  ::GetProcAddress(m_hDLL, "registerPlugin")
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 dllexport 从 DLL 导出函数 的相关文章

  • 如何从具有管理员权限的应用程序接收键盘输入到非管理员应用程序?

    我编写了一个应用程序 该应用程序具有覆盖类型的窗口 可以通过热键显示和隐藏该窗口 而另一个应用程序具有焦点 所述另一个应用程序是一个以管理员权限运行的 DirectX 游戏 我已经尝试了 3 种可能的解决方案 以便在其他应用程序中按下我的热
  • 使用普通画布/文本输出更新LayeredWindow

    有没有一种方法可以使用画布在表单上绘图 然后使用 updatelayeredwindow 这样表单就不可见 但文本可见 就像只显示文本的半透明表单一样 如果没有 那么有没有办法只用画布 opengl directx 制作某种半透明形式 我想
  • 使用 Windows 电源管理 API 调暗显示器

    我正在尝试做一些看起来很简单的事情 我只想让我的程序能够在某些条件下调整显示器亮度 于是 我向窗户望去电源管理API http msdn microsoft com en us library aa373163 28v vs 85 29 a
  • 使用createremotethread注入dll

    createremotethread如何在进程内执行dll 它使用的参数之一是 loadlibraryA 所以我得到了它在进程中执行 loadlibrary 函数的部分 然后它应该将上下文切换到内核模式 dll 是否由具有 loadlibr
  • Visual Studio 2019 能否将所需的 DLL 打包到一个小的 .exe 文件中?

    我使用 Visual Studio 2019 使用 C WinAPI 制作了一个 Windows 应用程序 完成后 我构建了它 并在我的计算机上执行 它工作完美 然后我发给我没有Visual Studio的朋友 它说需要 msvcp140d
  • 使用 xerces 链接 DLL 会给出未定义的符号

    我正在使用 cygwin 创建一个共享库 DLL 它使用 Xerces 当我从主应用程序调用 xercesc 函数时 一切都很好 但是当我尝试将一些代码放入库中时 我会得到 xerxesc 定义的所有静态内容的未定义符号 例如 std st
  • 在按钮背景上拉伸/收缩时,位图会失去质量

    简介及相关信息 我有一个所有者绘制的静态控件 它应该在渐变背景上有位图 静态控制尺寸不固定 它们是在创建父窗口期间计算的 我从资源文件加载背景颜色为 RGB 255 163 94 的位图 Using TransparentBlt RGB 2
  • 32 位键盘挂钩意外地在 64 位应用程序中工作,但挂起 Outlook

    我已经读了很多关于这个问题的文章 但情况却变得更加混乱 我有一个 32 位应用程序 它安装了 KeyboardHook 来等待全局热键并唤醒 在 Win 7 x64 版本上运行它 我注意到按下热键时它会挂起 Outlook x64 版本 所
  • 来自外部 DLL 的未处理的 DivideByZero 异常 - C#

    我有一个 C net 4 0 程序 其主要功能是从外部 FTP 库 项目引用的 dll 调用方法 逻辑位于 try catch 块中 catch 会打印错误 异常处理程序有一个通用参数 catch Exception ex IDE是VS 有
  • 是否有与 gcc --kill-at 等效的 Visual C++?

    也就是说 DLL 名称末尾有一个额外的 8 这会造成问题 显然 在 gcc 中使用 kill at 标志可以解决这个问题 但我找不到任何类似的 MSVC 建议 编辑 更多信息 我试图让 C JNI dll 工作 但我总是得到 线程 Thre
  • nmake 无法使用 VS 2012 编译 TSF 示例

    我正在尝试建立文本服务框架示例代码 http archive msdn microsoft com tsf Release ProjectReleases aspx ReleaseId 1755在 Windows 8 RC 64 位上使用
  • Inno Setup 以字符串作为参数调用 DLL

    当我尝试使用 Inno Setup 脚本中的 DLL 时 出现异常 我认为问题出在dll代码中的这一行 StreamReader sreader new StreamReader newpath 如果我将路径硬编码为 D source tx
  • 如何调用 LogonUser() 来获取启用了 UAC 的 Windows 服务中的非限制完整令牌?

    我正在 Windows Server 2012 上运行 WindowsService 它需要模拟域管理员用户 该用户也被添加到计算机上的本地管理员组 系统上启用了 UAC 并且使用 LogonType 为 LOGON32 LOGON INT
  • HBRUSH 转 RGB 值

    你能得到RGB值吗HBRUSH或者从刷子ID 例如 我正在寻找GRAY BRUSH以 RGB 值表示 您想使用获取对象 http msdn microsoft com en us library windows desktop dd1449
  • C# 4.0 动态对象和 WinAPI 接口,如 IShellItem(无需在 C# 源代码中定义它们)

    是否可以 使用 C 4 0 中的新动态关键字 使用接口 如 IShellItem 或其他 WinAPI 接口 而无需在 C 源代码中定义它们 或者至少不定义接口成员 我正在尝试类似的事情 const string IShellItemGui
  • 在 Windows 中从文件名获取驱动器号

    是否有 Windows API 函数可以从 Windows 路径中提取驱动器号 例如 U path to file txt U path to file txt 在正确整理的同时 relative path to file txt alte
  • 新显卡上的 nvoglv32.dll 中的绘制调用崩溃

    几天前 由于一些硬件更改 我设置了计算机并安装了新的 Windows 8 副本 其中 我将显卡从 Radeon HD 7870 更改为 Nvidia GTX 660 再次设置 Visual Studio 11 后 我从 Github 下载了
  • 如何使用 win32com.client api 访问 MS Word 的脚注

    我正在尝试使用 win32com client api 访问 MS Word 文件的脚注 我已经用谷歌搜索过 但没能找到合适的方法 我使用 python docx 来实现上述目的 但我发现当前版本的 python docx 无法访问 MS
  • MoveWindow死锁?

    我在线程 A 上有一个窗口 它在某个时刻 由于在其 wndproc 上收到消息 触发线程 B 上的操作 然后等待该操作完成 使用某种同步机制 然后线程B调用MoveWindow 在线程 A 的窗口 例如标准文本框 内移动子窗口 此时程序由于
  • 将 char[] 转换为 LPCWSTR

    谁能帮我纠正这个代码 char szBuff 64 sprintf szBuff p m hWnd MessageBox NULL szBuff L Test print handler MB OK 错误是 它无法将第二个参数转换为 LPC

随机推荐

  • 本地化数据库字段中的邮政/实际地址显示

    谁能向我指出国际邮政 住宅 送货地址格式模板的列表 这些模板使用某种可解析的标准词汇作为地址部分 理想的列表包含一个国家 地区代码 然后是使用可替换标记的格式 以便我可以将数据库地址字段替换到模板中以生成可本地格式打印的内容 例如 NZ f
  • 如何将数据存储到android中的Secure Element中

    我想在 Android 中创建一个类似谷歌钱包的应用程序 据说 所有支付凭证都存储在一个名为安全元件包含在手机中 我如何访问它安全元件并将我的卡凭证存储到其中 我的目标是在收银台使用我的手机 Nexus 而不是我的卡 所以我想要的是将一些数
  • 更新和替换字符串的一部分

    我有一个有两列的表格 ID and Value 我想更改第二列中一些字符串的一部分 表格示例 ID Value 1 c temp 123 abc 111 2 c temp 123 abc 222 3 c temp 123 abc 333 4
  • 执行ContentResolver插入时出错

    执行插入新数据到内容提供程序时出错 请参见下面的代码 PS 我只是将下面的代码直接放入 Activity 的 onCreate 中 然后执行 ContentValues values new ContentValues values put
  • 谁定义了正则表达式?

    W3C 定义了 HTML 标准 CSS 标准和一些其他标准 我知道还有其他团体也定义了标准 谁定义了正则表达式的语法 正则表达式由多个标准机构涵盖 包括 IEEE 标准 1003 1 所谓的 Posix http pubs opengrou
  • 将 UTC 日期转换为日期时间字符串 Titanium

    我有一个日期字符串 2012 11 14T06 57 36 0000 我想转换为以下格式 2012 年 11 月 14 日 12 27 我尝试了很多解决方案 包括将 UTC 日期转换为日期时间字符串 Javascript https sta
  • 将随机排列代码从 MATLAB 移植到 Python

    如何将这段 MATLAB 代码转换为 Python 例如 对于随机文件 FileA rand 10 2 FileB randperm 10 for i 1 10 fileC FileB i 1 FileA i 1 for the x fil
  • PyQt QMediaPlayer setPosition 对位置值进行四舍五入

    我有一个应用程序 旨在帮助同步实验视频和数据信号 该应用程序有一个视频小部件和一个滑块 可以设置视频的时间位置 然而 QMediaPlayer 只会以 500 毫秒 1000 毫秒的间隔设置位置 在我的应用程序中为 500 毫秒 在设计的应
  • Javascript 和 PHP 中十进制转 RGB

    我正在尝试将十进制值转换回 RGB 值 假设这是编译十进制值的公式 c r 255 255 g 255 b 例如 rgb 16 120 78 加起来是 1071078 如何在没有任何 溢出 的情况下求解 r g 和 b 提前致谢 使用除法
  • 我的 NDK 项目因 CPU 架构相关问题而无法编译

    有人可以解释一下为什么我会收到此错误吗 Build command failed Error while executing process C Users Kevin Desktop Android Sdk ndk bundle ndk
  • Dalvik的内存模型和Java的一样吗?

    Dalvik的内存模型和Java s http java sun com docs books jls third edition html memory html 17 4 我特别感兴趣的是是否读写参考和非long non double原
  • 在CALayer中添加UIImage

    我必须添加 UIImageView 作为 MapView 的子视图 为此 我在 MapView 上方创建了一个图层 在这一层中 我想放置我的图像 但我得到一个白色矩形 没有其他东西 我的图像不可见 这是代码 void viewDidLoad
  • 每当我创建新的 Rails 应用程序时,如何创建 Postgres 用户和数据库?

    我遵循了这个非常有用的教程 http blog willj net 2011 05 31 setting up postgresql for ruby on rails development on os x http blog willj
  • glewInit() 因“缺少 GL 版本”、SDL2 OpenGL 上下文、cygwin 编译器而失败

    下面的程序创建一个窗口 该窗口除了按 esc 关闭外不执行任何操作 当我用cygwin编译它时 没有错误 我使用的GLEW来自CYGWIN 端口 http cygwinports org SDL2 是版本 2 0 3 来自他们的websit
  • WPF 与 Unity 容器 - 如何注册 ViewModel 并将其解析为 View

    您好 我正在尝试在 WPF MVVM 应用程序中使用 Unity 容器 我没有使用过 Prism 因为它看起来很重 这是应用程序结构 我试图弄清楚如何将视图解析为视图模型以及视图模型 服务 的依赖关系 应用 Views MainWindow
  • 如何更改 UIDatePicker 色调颜色?

    我知道 UIDatePicker 无法自定义 但我想知道 iOS 14 提醒应用程序如何显示蓝色色调 而日历显示红色色调 我将 AppDelegate 中的全局色调设置为 label如下所示 但无法为日期选择器设置相同的值 UIView a
  • Debugdiag 显示“Microsoft VC 运行时堆”使用超过 1GB

    您好 我的 WPF 应用程序存在泄漏 我正在尝试使用内存转储文件来查找问题所在 使用 WinDbg 和 SOS 我找不到任何可疑的东西 然后我尝试了 DebugDiag 我得到了Microsoft VC 运行时堆 私有 有 1 42 GB
  • Dart DateTime.parse timeZoneOffset 始终为 0

    DateTime parse 创建的 DateTime 似乎总是为 timeZoneOffset 返回 0 我在非 UTC 时区中创建了一个 ISO8601 字符串 https timestampgenerator com 16100103
  • 如何使 say 命令回显脚本中的变量值?

    我使用的是 Mac 有时我会使用say命令位于我的脚本末尾 如下所示 system say Finished successfully 但如果我尝试插入一个变量 system say my variable 它不起作用 它仅回显变量名称 我
  • 使用 dllexport 从 DLL 导出函数

    我想要一个从 C Windows DLL 导出函数的简单示例 我想看看标题 cpp文件 以及 def文件 如果绝对需要 我希望导出的名称是未装饰的 我想使用最标准的调用约定 stdcall 我想要使 用 declspec dllexport