Использование массивов и указателей в C # с C DLL - PullRequest
1 голос
/ 12 апреля 2009

Я очень плохо знаком с C # (только начал учиться на прошлой неделе).

У меня есть пользовательская DLL, написанная на C со следующей функцией:

DLLIMPORT void test_function (double **test)

Я хочу получить указатель из C # для массива 'test'.

Итак, если в функции DLL у меня есть test [0] = 450.60, test [1] = 512.99 и т. Д., Я хочу, чтобы это было доступно в моей программе на C #.

В программе на C # у меня есть нечто похожее на:

namespace TestUtil
{
  public class Echo
  {
    public double[] results = new double[10];
    public double[] results_cpy = new double[10];


    [DllImport("test_dll.dll", CallingConvention = CallingConvention.Cdecl)]
    static extern unsafe void test_function(ref double[] Result);

    public unsafe void Tell()
    {
      results[0] = 0.0;
      results[1] = 0.0;

      results_cpy[0] = 0.0;
      results_cpy[1] = 0.0;

      test_function(ref results);
      results_cpy[0] = (double)results[0] + (double)results[1] ;
    }
  }
}

В функции DLL «test_function» я использовал следующее:

*test[0] = 450.60;
*test[1] = 512.99;

Внутри DLL все было в порядке (я использовал окно сообщения внутри DLL, чтобы проверить, применяются ли значения). Вернувшись в программу на C #, «results [0]» выглядит нормально, и я могу получить из нее значения, но «results [1]» дает мне ошибку индекса за пределами границ. Я знаю это, потому что если я опущу '+ (double) results [1]', я не получу ошибку. Кроме того, если я не попытаюсь изменить DLL в test [1], она сохранит исходное значение из C # (в моем примере 0.0).

Очевидно, я не делаю что-то правильно, но это самое близкое, что я смог сделать, чтобы это сработало вообще. Все остальное, что я пробовал, с треском проваливается.

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

5 голосов
/ 12 апреля 2009

Нет необходимости в небезопасном коде. На самом деле, нет необходимости передавать по ссылке вообще. Если ваша подпись выглядит так:

void test_function (double *test)

и ваш импорт выглядит так:

static extern void test_function(double[] Result);

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

1 голос
/ 12 апреля 2009

Полагаю, вы уже знаете C ++; если это так, вам действительно стоит взглянуть на C ++ / CLI, который позволяет легко использовать управляемый код (.NET) из C ++. Код, который вы показали выше, действительно не очень похож на C # (вам следует полностью избегать unsafe).

0 голосов
/ 12 апреля 2009

Подобный вопрос по SO здесь . Вы смотрите на непрозрачный указатель, так что это скорее всего система InPtr, как описано в другом потоке.

Кстати, почему бы не сделать его двойным * вместо двойного **. Думаю, это облегчит жизнь.

0 голосов
/ 12 апреля 2009

Я не уверен, что происходит не так, но я, безусловно, могу указать вам статью, в которой говорится о p / invoke. посмотрим, поможет ли это вам.

http://msdn.microsoft.com/en-us/magazine/cc164123.aspx

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