Visual C++:从 DLL 调用时 XGBoost 不起作用
Posted
技术标签:
【中文标题】Visual C++:从 DLL 调用时 XGBoost 不起作用【英文标题】:Visual C++ : XGBoost does not work when called from a DLL 【发布时间】:2018-08-06 22:31:15 【问题描述】:我需要在 Visual C++ 项目 DLL 中使用 XGBoost。 我已经能够使用 VC++ 和 CMake 下载和构建 XGBoost 源代码。
当我在测试控制台应用程序中包含 XGBoost 代码时,它工作正常。
但是,当我尝试在 DLL 项目中复制我对控制台应用程序所做的操作时,它不会编译。 我什至很难在项目中使用基本的 XGBoost 类型。
我怀疑问题在于我对 DLL 项目的无知,希望您能提供帮助。
以下是我的 DLL 项目中发生的情况:
当我使用以下包含作为 cpp 类文件的第一行时,它会编译:#include <xgboost\c_api.h>
编译后,如果我尝试使用此包含文件中定义的简单类型,则构建失败并显示以下消息: ...\dll_test\xgb_driver.cpp(20):错误 C2065:“BoosterHandle”:未声明的标识符
这是导致错误的行:BoosterHandle my_handle;
“BoosterHandle”实际上是在<xgboost\c_api.h>
中定义的
当我将包含置于任何其他包含之下时,我收到以下错误消息: 1>c:\tools\src\xgboost\include\xgboost\c_api.h(29):错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int
1>c:\tools\src\xgboost\include\xgboost\c_api.h(29): 错误 C2146: 语法错误: 缺少 ';'在标识符“bst_ulong”之前
下面是关于我如何让 XGBoost 与控制台应用程序一起工作以及我如何创建 DLL 项目的更多信息。
=-=-=-=-=-=
这是我在控制台中使用 XGBoost 时所做的。关于它的一切似乎都有效。我已经测试了模型预测,它们是 与我在 R 中看到的一致。
使用此处找到的文档: https://xgboost.readthedocs.io/en/latest/build.html
我下载了 XGBoost 源代码并使用 CMake 和 Visual Studio 2015 构建它。
在项目 > 链接器 > 输入 > 附加依赖项下, 我添加了 xgboost.lib 文件
在项目下 > 链接器 > 常规 > 附加库目录 我添加了对 ...\xgboost\build\Release
的引用在项目下 > VC++ 目录 > 包含目录 我将路径添加到 ...\xgboost\rabit\include 和 ...\xgboost\include
我把xgboost.dll放在生成.exe的目录下。
从这里开始,一帆风顺。
=-=-=-=-=-=
这是我为创建 Visual C++ DLL 项目所做的工作:
选择文件 > 新建 > 项目后,我选择了一个 ATL DLL 项目(这是项目要求的一部分)。
对于项目中包含的 XGBoost,我重复了上面的步骤 1-5,但将 xgboost.dll 文件放在了 将生成项目 DLL。
这是我创建的简单类的头文件的来源:
#pragma once
class XGB_Driver
public:
XGB_Driver();
~XGB_Driver();
float callXGB(float sample_input);
;
这里是简单 cpp 文件的来源:
#include <xgboost/c_api.h>
#include "stdafx.h"
#include "XGB_Driver.h"
XGB_Driver::XGB_Driver()
XGB_Driver::~XGB_Driver()
float XGB_Driver::callXGB(float simple_input)
BoosterHandle my_handle;
return(0);
为什么这对 ATL DLL 项目不起作用,但对控制台应用程序却起作用,这真的让我头疼不已。
非常感谢您的帮助。
最好, 戴夫
【问题讨论】:
如果你#include <cstdint>
之前 #include <xgboost/c_api.h>
会发生什么?或者更好,如果您将#include "stdafx.h"
移到#include
s 列表的顶部?
CristiFati,在 xgboost 标头之前添加的#include #include "stdafx.h"
怎么样?如果仅此一项不起作用,则应将 #include <cstdint>
放在 StdAfx.h 中。这就是应该这样做的方式。让我知道它是否适合您,然后我会发布一个带有解释和所有内容的答案。
它有效,如果你能详细说明它为什么有效,我将不胜感激。
另一方面,我不理解问题第一部分中的错误,此时构建 xgboost 对我来说开销太大。所以,继续回答你自己的问题。
【参考方案1】:
在 CristiFati 的帮助下,我相信这个问题已经得到解答。
无论出于何种原因,在 DLL 项目中使用带有 C++ 的 XGBoost 似乎需要额外的包含,超出在控制台应用程序中使用它所需的内容。
我目前正在构建 DLL 项目,并添加了:#include <cstdint>
【讨论】:
以上是关于Visual C++:从 DLL 调用时 XGBoost 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual Studio 6 中从 VB 调用 VS2010 C++ dll
Visual Lisp:如何调用外部 C++ DLL 中的函数