Выделение структуры C, содержащей массивы в C # - PullRequest
10 голосов
/ 03 декабря 2011

С помощью сообщества stackoverflow мне удалось вызвать встроенную функцию DLL.Однако я не могу изменить значения массива ID или intersects.Независимо от того, что я делаю с ним на стороне DLL, старое значение остается.Он доступен только для чтения.

Вот некоторые фрагменты кода:

C ++ struct:

typedef struct _Face {
    int ID;
    int intersects[625];
} Face;

C # mapping:

[StructLayout(LayoutKind.Sequential)]
    public struct Face {
        public int ID;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 625)]
        public int[] intersects;
    }

C ++ метод(введите значение DLL в VS2010):

extern "C" int __declspec(dllexport) __stdcall 
solve(Face *faces, int n){
for(int i =0; i<n; i++){
    for(int r=0; r<625; r++){
        faces[i].intersects[r] = 333;
        faces[i].ID = 666;
        }
    }

Подпись метода C #:

[DllImport("lib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern int solve(Face[] faces, int len);

Вызов метода C #:

Face[] faces = new Face[10];
faces[0].intersects = new int[625];
faces[0].ID = -1; //.. and add 9 more ..

solve(faces, faces.Length);

// faces[0].ID still equals -1 and not 666

С наилучшими пожеланиями, e.

Ответы [ 2 ]

8 голосов
/ 03 декабря 2011

Вы должны явно указать маршаллеру pinvoke, что массив нужно маршалировать обратно. Вы делаете это с помощью атрибутов [In] и [Out]. Как это:

    [DllImport("...")]
    public static extern int solve([In, Out] Face[] faces, int len);
0 голосов
/ 03 декабря 2011

Это только поле вывода?Чтобы разобраться в этом, я бы попробовал заменить ваш параметр Face [] байтом [], достаточно большим, и посмотреть, не заполнится ли чем-нибудь байтовый массив (вам придется немного изменить [DllExport].).

Кроме того, еще одна вещь, с которой я сталкивался при работе с char *, - это то, что мне пришлось предварительно выделить буфер в C #.Например:

StringBuilder theString=new StringBuilder();
MyUnmanagedFunction(theString);

не будет работать.Но предполагая, что возвращаемое значение theString было максимум 256 символов, я бы сделал это:

StringBuilder theString=new StringBuilder(256);
MyUnmanagedFunction(theString);

И я бы занимался бизнесом.Я бы рекомендовал попробовать замену byte [], если это не сработает, попробуйте предварительно выделенный байтовый массив.Как только вы увидите, что байтовый массив действительно изменяется вашим кодом C ++, вы можете выяснить, как разместить эту вещь в вашей структуре C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...