簡體   English   中英

C和System.AccessViolationException中的allocVector():嘗試讀取或寫入受保護的內存嗎?

[英]allocVector() in C and System.AccessViolationException: Attempted to read or write protected memory?

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

#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

快速閱讀,我認為您使用值6作為指針的值。 那里還有其他問題。

退一步,我為您的C#/ C互操作提出一些建議:

  • 如果此API中沒有很多自己的C代碼,建議您將其移植到C#並使用R.NET( NuGet軟件包源代碼
  • 如果您確實有大量的C / C ++代碼,或者絕對需要C層,則可以查看此示例代碼 在回答之前,我將它們放在一起進行了一些測試,所以我不妨提交源代碼。

為了其他讀者,從問題中的功能闡述的重點是:

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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM