2016-11-14 59 views
-1

我正在嘗試使用XGBoost's dll(libxgboost.dll)創建一個DMatrix(就像一個二維數組),並獲取它有多少個列。它運行正常,直到它在下面的代碼拋出一個System.AccessViolationExceptionint 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函數的定義:

XGDMatrixCreateFromFile()

/*! 
* \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); 

XGDMatrixNumCol()

/*! 
* \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的副本。

+0

'Marshal.AllocHGlobal(10);'分配10個字節還是10個整數?你有多確定只有10列? –

+0

我認爲它分配10個字節,如果我正在閱讀[文檔](https://msdn.microsoft.com/en-us/library/s69bkh17(v = vs.110).aspx)的權利。 10只是我用來在內存中存儲一​​個整數的任意數量的字節(它可以指多於10列)。 – cycloidistic

+0

如果XGDMatrixNumCol填充bst_ulong參數,那麼您需要知道bst_ulong有多大 - 是多少還是少於10個字節? –

回答

-1

這是我得到的解決方案,謝謝NineBerry's answer

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, out IntPtr outputPtr); 

    [DllImport("../../libs/libxgboost.dll", CharSet = CharSet.Auto)] 
    public static extern int XGDMatrixNumCol(IntPtr dmatrixPtr, out ulong dmatrixColumnsPtr); 

    static void Main(string[] args) 
    { 
     IntPtr dmatrixPtr; 
     ulong dmatrixColumns; 

     int result = XGDMatrixCreateFromFile("../../libs/test.txt", 0, out dmatrixPtr); 
     int cols = XGDMatrixNumCol(dmatrixPtr, out dmatrixColumns); 
    } 
    } 
} 
+1

檢查返回值。他們在那裏是有原因的。 XGDMatrixCreateFromFile可能會失敗。 – MarcD

相關問題