Передача данных массива между C # и DLL (в обоих направлениях) - PullRequest
3 голосов
/ 19 апреля 2011

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

Вот что у меня есть. Из C # работает только функция bar (). Возвращает 22 и записывает в файл, как и ожидалось. Другие записывают в свои файлы правильно, но выдают исключение, когда управление возвращается обратно в C #. Это читает,

"При вызове функции PInvoke 'irhax! Irhax.App :: foo' разбалансирован стек подпись соответствует целевой неуправляемой подписи. "

C (DLL):

#define IG_API __declspec(dllexport)

IG_API void foo(int i) {
    FILE *f = fopen("foo.txt", "a+");
    fprintf(f, "%d\n", i);
    fclose(f);
}

IG_API int bar(void) {
    FILE *f = fopen("bar.txt", "a+");
    fprintf(f, "bar!\n");
    fclose(f);
    return 22;
}


IG_API void transmitIR(unsigned *data, int length) {
    FILE *f = fopen("transmit.txt", "a+");
    for(int i = 0; i < length; ++i)
        fprintf(f, "%d, ", data[i]);
    fprintf(f, "\n");
    fclose(f);
}

IG_API int receiveIR(unsigned *data, int length) {
    for(int i = 0; i < length; ++i)
        data[i] = 4;
    return length;
}

C # (звонящий):

[DllImport("Plugin.dll")]
static extern void foo(int i);

[DllImport("Plugin.dll")]
static extern int bar();

[DllImport("Plugin.dll")]
static extern void transmitIR(uint[] data, int length);

[DllImport("Plugin.dll")]
static extern int receiveIR(out uint[] data, int length);

Я в недоумении. Что я делаю неправильно? Поскольку я даже не могу заставить foo (int) работать, это хорошее начало.

Ответы [ 2 ]

6 голосов
/ 19 апреля 2011

Ваш код на C использует соглашение о вызовах cdecl.Код C # использует stdcall.

Все атрибуты DLLImport должны быть:

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)]

Конечно, вы можете альтернативно переключить код C на стандартный вызов, используя __stdcall.Но убедитесь, что вы делаете только один из них!

receiveIR не нуждается в out.Вы должны объявить это:

static extern int receiveIR(uint[] data, int length);
1 голос
/ 19 апреля 2011

Знаете ли вы соглашение о вызовах функций C? Как говорится в ошибке, это, вероятно, несоответствие. Соглашение о вызовах по умолчанию - stdcall, но если эти функции используют соглашение cdecl, вы, скорее всего, получите эту ошибку. Попробуйте

[DllImport("Plugin.dll", CallingConvention=CallingConvention.Cdecl)]
static extern void foo(int i);
...