Параметры Stull DllImport - PullRequest
0 голосов
/ 04 ноября 2011

У меня есть 3 структуры C ++, а также два метода, и я хочу использовать их через C #.Вот мой код C # и несколько комментариев к коду C ++.

[StructLayout(LayoutKind.Sequential)]
public unsafe struct smat
{
    public long rows;
    public long cols;
    public long vals;     
    public long* pointr;  
    public long* rowind;  
    public double* value; 
};

[StructLayout(LayoutKind.Sequential)]
public unsafe struct dmat {
    long rows;
    long cols;
    double **value;
};

[StructLayout(LayoutKind.Sequential)]
public unsafe struct svdrec {
    int d;      
    dmat Ut;    // it was dmat* in C++
    double *S;  
    dmat Vt;    // it was dmat* in C++
};

[DllImport(@"file.dll", EntryPoint = "svdNewSMat", CallingConvention = CallingConvention.Cdecl)]
public static extern smat svdNewSMat(int rows, int cols, int vals); // it was smat* in C++

[DllImport(@"file.dll", EntryPoint = "svdLAS2", CallingConvention = CallingConvention.Cdecl)]
    public static extern svdrec svdLAS2(smat a, long dimensions, long iterations, double[] las2end, double kappa); // it was smat* and svdrec* in C++

РЕДАКТИРОВАТЬ: Вот заголовки C ++

typedef struct smat *SMat;
typedef struct dmat *DMat;
typedef struct svdrec *SVDRec;

/* Harwell-Boeing sparse matrix. */
struct smat {
  long rows;
  long cols;
  long vals;     /* Total non-zero entries. */
  long *pointr;  /* For each col (plus 1), index of first non-zero entry. */
  long *rowind;  /* For each nz entry, the row index. */
  double *value; /* For each nz entry, the value. */
};

/* Row-major dense matrix.  Rows are consecutive vectors. */
struct dmat {
  long rows;
  long cols;
  double **value; /* Accessed by [row][col]. Free value[0] and value to free.*/
};

struct svdrec {
  int d;      /* Dimensionality (rank) */
  DMat Ut;    /* Transpose of left singular vectors. (d by m)
             The vectors are the rows of Ut. */
  double *S;  /* Array of singular values. (length d) */
  DMat Vt;    /* Transpose of right singular vectors. (d by n)
             The vectors are the rows of Vt. */
};

extern DMat svdNewDMat(int rows, int cols);
extern SVDRec svdLAS2(SMat A, long dimensions, long iterations, double end[2], 
                  double kappa);

Iя не даю полный код, потому что он включает в себя множество библиотек. И вот что я исключаю из теста:

var a = svdNewSMat(3, 6, 3);
var m = new double[] {1, 2};
var r = svdLAS2(a, 1, 0, m, 1e-6); // I get the Exception here

Вторая строка дает мне Попытка чтения или записи в защищенную память ошибка.Есть идеи?Заранее спасибо.

Ответы [ 5 ]

1 голос
/ 04 ноября 2011

Вы не можете просто заменить dmat * на dmat на стороне C #.Указатель не распределяется автоматически как ссылка

Пожалуйста, посмотрите http://msdn.microsoft.com/en-us/library/0szztey7(v=vs.80).aspx о том, как правильно упорядочить встроенные указатели.

1 голос
/ 04 ноября 2011

Вы можете просто использовать IntPtr, если работаете с указателями из DLL.Помните, что во время этой работы произойдет много коробок / распаковок.

1 голос
/ 04 ноября 2011

Если это были smat * и dmat *, используйте IntPtr вместо smad / dmat.

0 голосов
/ 04 ноября 2011

В объявлениях функций pinvoke, эквивалентный указателю на указатель, обычно равен ref IntPtr В объявлении структуры (и, как указывали другие), оно должно быть просто IntPtr. Имейте в виду, что при вызове функций все зачастую сложнее, чем просто получить правильные объявления структуры (например, может потребоваться изменить соглашения о вызовах).

0 голосов
/ 04 ноября 2011

Я не верю, что модуль c ++ может выполнять операции над ac # struct.

Попробуйте использовать класс вместо struct.

...