我正在尝试使用XGBoost's dll(libxgboost.dll)创建一个DMatrix(就像一个二维数组),并获取它有多少个列。它运行正常,直到它在下面的代码抛出一个System.AccessViolationException
在int cols = ...
行:为什么访问非托管内存会导致System.AccessViolationException?
using System;
using System.Runtime.InteropServices;
namespace basicXgboost
{
class Program
{
[DllImport("../../libs/libxgboost.dll", CharSet = CharSet.Auto)]
public static extern int XGDMatrixCreateFromFile([MarshalAs(UnmanagedType.LPStr)] string file, int silent, IntPtr outputPtr);
[DllImport("../../libs/libxgboost.dll", CharSet = CharSet.Auto)]
public static extern int XGDMatrixNumCol(IntPtr dmatrixPtr, IntPtr dmatrixColumnsPtr);
static void Main(string[] args)
{
IntPtr dmatrixPtr = Marshal.AllocHGlobal(1000000);
IntPtr dmatrixColumnsPtr = Marshal.AllocHGlobal(10);
int result = XGDMatrixCreateFromFile("../../libs/test.txt", 0, dmatrixPtr);
int cols = XGDMatrixNumCol(dmatrixPtr, dmatrixColumnsPtr);
Marshal.FreeHGlobal(dmatrixPtr);
Marshal.FreeHGlobal(dmatrixColumnsPtr);
}
}
}
为什么访问非托管内存XGDMatrixNumCol(dmatrixPtr, dmatrixColumnsPtr)
事业System.AccessViolationException
分配呢?
一种可能性可能是我对这些功能使用了不正确的pinvoke。下面是我使用的每个DLL函数的定义:
/*!
* \brief load a data matrix
* \param fname the name of the file
* \param silent whether print messages during loading
* \param out a loaded data matrix
* \return 0 when success, -1 when failure happens
*/
XGB_DLL int XGDMatrixCreateFromFile(const char *fname,
int silent,
DMatrixHandle *out);
/*!
* \brief get number of columns
* \param handle the handle to the DMatrix
* \param out The output of number of columns
* \return 0 when success, -1 when failure happens
*/
XGB_DLL int XGDMatrixNumCol(DMatrixHandle handle,
bst_ulong *out);
Here是我的项目的回购协议。我正在使用Visual Studio Enterprise 2015。它在Windows 10 Pro(64位)上以“调试”模式(目标x64)构建。可以找到libxgboost.dll的x64二进制文件here。虽然链接的回购确实包含libxgboost.dll的副本。
'Marshal.AllocHGlobal(10);'分配10个字节还是10个整数?你有多确定只有10列? –
我认为它分配10个字节,如果我正在阅读[文档](https://msdn.microsoft.com/en-us/library/s69bkh17(v = vs.110).aspx)的权利。 10只是我用来在内存中存储一个整数的任意数量的字节(它可以指多于10列)。 – cycloidistic
如果XGDMatrixNumCol填充bst_ulong参数,那么您需要知道bst_ulong有多大 - 是多少还是少于10个字节? –