Visual C++:从 DLL 调用时 XGBoost 不起作用

Visual C++ : XGBoost does not work when called from a DLL

我需要在 Visual C++ 项目 DLL 中使用 XGBoost。 我已经能够使用 VC++ 和 CMake 下载并构建 XGBoost 源代码。

当我在测试控制台应用程序中包含 XGBoost 代码时,它工作正常。

但是,当我尝试在 DLL 项目中复制我对控制台应用程序所做的操作时,它无法编译。 我什至难以在项目中使用基本的 XGBoost 类型。

我怀疑问题是我对 DLL 项目的无知,非常感谢你的帮助。

这是我的 DLL 项目中发生的事情: 当我使用以下包含作为 cpp class 文件中的第一行时,它会编译:
#include <xgboost\c_api.h>

编译时,如果我尝试使用此包含文件中定义的简单类型,构建将失败并显示以下消息:
...\dll_test\xgb_driver.cpp(20): error C2065: 'BoosterHandle': 未声明的标识符

这是导致错误的行:
BoosterHandle my_handle;

"BoosterHandle"实际上是在<xgboost\c_api.h>

中定义的

当我将 include 放在任何其他 include 之下时,我收到以下错误消息:
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

  1. 我下载了 XGBoost 源代码并使用 CMake 和 Visual Studio 2015 构建了它。

  2. 在项目 > 链接器 > 输入 > 附加依赖项下, 我添加了 xgboost.lib 文件

  3. 在“项目”>“链接器”>“常规”>“其他库目录”下 我添加了对 ...\xgboost\build\Release

  4. 的引用
  5. 在项目下 > VC++ 目录 > 包含目录 我将路径添加到 ...\xgboost\rabit\include 和 ...\xgboost\include

  6. 我把xgboost.dll放在生成.exe的目录下

从这里开始,一帆风顺。

=-=-=-=-=-=

以下是我创建 Visual C++ DLL 项目所做的工作:

选择文件 > 新建 > 项目后,我 select 一个 ATL DLL 项目(这是项目要求的一部分)。

为了将 XGBoost 包含到项目中,我重复了上面的步骤 1-5,但将 xgboost.dll 文件放在了 将生成项目 DLL。

这是我创建的简单 class 头文件的来源:

#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 项目不起作用,但对控制台应用程序却起作用,这真的让我头撞键盘。

非常感谢您的帮助。

最好的, 戴夫

在 CristiFati 的帮助下,我相信这个问题已经得到解答。 无论出于何种原因,似乎在 DLL 项目中使用 XGBoost 和 C++ 需要额外的包含,超出在控制台应用程序中使用它所需的内容。
我目前正在构建 DLL 项目并添加:
#include <cstdint>