我試圖使用XGBoost's DLL(libxgboost.dll)創建DMatrix(這就像一個二維數組),並把它多少列了。它運行正常,直到它在下面的代碼拋出一個System.AccessViolationException
在int cols = ...
行:使用XGBoost DLL從C通過P#/調用
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的副本。
不要讓我們通過場外代碼打獵。即使如此,我們如何才能知道每個功能的要求是什麼?你有沒有可用的示例C++代碼。 –
對不起。我不想通過複製粘貼所有C++定義來使問題時間過長。你能澄清你的意思是什麼樣的C + +代碼?我正在用C#編寫這個代碼,一切都到了「int cols = ...」這行似乎正在工作。 – cycloidistic
這個問題沒有任何重要的細節。 –