Запись в массив C # из C с помощью PInvoke - PullRequest
1 голос
/ 27 марта 2012

У меня есть такая функция:

extern "C" __declspec(dllexport) void Step(int * oSamplesCount, float * oSamples){
    // (approximative syntax for clarity)
    *oSamplesCount = new_samples_count (some number between 0 and 16000)
    oSamples[ 0 .. new_samples_count ] = some floats (sound data)
}

Я бы хотел вызвать ее из C #:

float [] mSamples = new float[16000];

[DllImport("Lib.dll")]
static extern void Step(ref Int32 oSamplesCount, [MarshalAs(UnmanagedType.LPArray,SizeConst=16000)] ref float [] oSamples);

void update(){
    Int32 lSamplesCount = 0;
    Step(ref lSamplesCount, ref mSamples);
}

Функция C вызывается правильно, цикл for ()с заполнением массива примеров все в порядке, но он падает где-то между строкой возврата и следующей строкой C #, так что я думаю, что это как-то связано с unmarshalling, хотя я не хочу, чтобы marshalling / unmarshalling (массив является blittable и должен бытьзаписано в C)

Я не могу использовать / небезопасно.Я пробовал SizeConst и другие варианты.

Любая помощь приветствуется!

1 Ответ

1 голос
/ 27 марта 2012

Ваш пинвоук неверен.Параметр массива не должен передаваться ref, поскольку float[] уже является ссылкой.Сделайте это следующим образом:

[DllImport("Lib.dll")]
static extern void Step(ref Int32 oSamplesCount, float[] oSamples);

Обратите внимание, что это приведет к переключению из управляемого в исходное и обратно всех 16000 значений при каждом вызове Step.Если это слишком дорого, я думаю, вам нужно выполнить ручную сортировку.

...