2015-06-06 60 views
0

我有一個allocVector()函數的問題。我用C編寫了一個可以在R中調用的代碼(DLL)。我想在C#中將該DLL的一個方法調用到我的應用程序中。 DLL代碼工作正常,但編譯器到達下一行ROut = allocVector(INTSXP,2 * 3) 它給出以下例外: 未處理的異常:System.AccessViolationException:試圖讀取或寫入受保護的內存。 的代碼如下:C和System.AccessViolationException中的allocVector():試圖讀取或寫入受保護的內存?

#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include <R.h> 
#include <Rinternals.h> 
#include <Rmath.h> 
#include <R_ext/Applic.h> 
#include <R_ext/Lapack.h> 
#include <Rdefines.h> 
#ifdef __cplusplus 
extern "C" { 
#endif 
    void castType(int *result) 
    { 
     SEXP ROut; 
     ROut = allocVector(INTSXP, 2*3) 
     ROut = PROTECT(ROut); 
     int *clustOut = INTEGER(ROut); 
     result= clustOut ; 
    } 
#ifdef __cplusplus 
} 
#endif 

回答

0

快速閱讀,我想你使用值6作爲指針的值。那裏還有其他的東西存在問題。

退一步,我建議兩件事情對你的C#/ C互操作:

  • 如果你沒有很多自己的現有的C代碼,此API中,我建議你口它到C#和使用R.NET(NuGet package,source code
  • 如果你確實有大量的C/C++代碼,或絕對需要C層,你可以看看這個sample code。在回答之前,我把它們放在一起來測試幾件事情,所以我也可以提供源代碼。

其他讀者起見,它的癥結從問題的功能闡述爲:

C API:

void c_api_call(int * result) 
{ 
    SEXP p = some_R_calculations(); 
    int* int_ptr = INTEGER_POINTER(p); 
    int n = length(p); 
    for (int i = 0; i < n; i++) 
     result[i] = int_ptr[i]; 
    // We are done with p; irrespective of where some_R_calculations got it, 
    // we can notify the R GC that this function releases it. 
    R_ReleaseObject(p); 
} 

C#互操作的包裝:

public class CppInterop : DynamicInterop.UnmanagedDll // http://www.nuget.org/packages/DynamicInterop/ 
{ 
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    private delegate void _c_api_call([In, Out] [MarshalAs(UnmanagedType.LPArray)] int[] values); 

    public int[] CreateArray() 
    { 
     // These two following references could be cached for efficiency later on. 
     var getLength = this.GetFunction<_c_api_call_getlength>("c_api_call_getlength"); 
     var getValues = this.GetFunction<_c_api_call>("c_api_call"); 

     // As far as I know it is preferable, if not needed, to handle arrays in two steps: 
     // we need to know the expected length to allocate in C# buffer memory. 
     int expectedLength = getLength(); 
     int[] result = new int[expectedLength]; 
     getValues(result); 
     return result; 
    } 
+0

謝謝您的回答。我遵循在代碼中使用rClr的方法,但編譯時遇到以下錯誤: –

+0

錯誤LNK1104:無法打開文件'Rdll.lib'\t C:\ Users \ Stephan \ Documents \ GitHub \ rdotnet-support \ wrapcppdll \ mycpp \ LINK \t mycpp –

+0

我也跟着下面的步驟因爲他們是所謂的網站CodePlex上建立我的系統上RCLR: %R%CMD檢查RCLR %R%CMD REMOVE RCLR %R%CMD INSTALL RCLR 我收到消息構建成功。 –

相關問題