.net обертка для родной DLL - как минимизировать риск ошибки во время выполнения? - PullRequest
5 голосов
/ 06 декабря 2011

Я занимаюсь разработкой приложения на C #.Поскольку у меня есть несколько алгоритмов подгонки наименьших квадратов в C / C ++, которые были бы слишком громоздкими и слишком переводимыми, я превратил код C ++ в dll, а затем создал оболочку в C #.

В коде C #Я определил структуру, которая передается в неуправляемый код C ++ в качестве указателя.Структура содержит начальные предположения для функций подбора, и она также используется для возврата результатов подбора.

Мне кажется, что вы должны определить структуру как в управляемом, так и в неуправляемом коде.Тем не менее, кто-то, кто использует мой исходный код в будущем, может решить изменить поля структуры в приложении C #, не понимая, что он также должен изменить структуру в собственном коде.Это в лучшем случае приведет к ошибке времени выполнения (а в худшем - к ошибочным результатам), но не будет сообщения об ошибке, сообщающего разработчику / конечному пользователю, что не так.

Насколько я понимаю, невозможносоздать тест в неуправляемой DLL C ++, который проверяет, содержит ли структура правильные поля, но возможно ли, чтобы DLL возвращала структуру правильного формата в оболочку C #?

В противном случае, какие существуют способыуменьшить риск того, что какой-то неосторожный программист в будущем вызовет ошибки времени выполнения, которые трудно обнаружить?

Пример кода:

//C++
struct InputOutputStruct {
    double a,b,c;
}

extern "C" __declspec(dllexport) void DoSomethingToStruct(InputOutputStruct* s)
{

// ... алгоритма

}

//C#
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
    public struct InputOutputStruct {
        public double a,b,c;
    }

[DllImport("CpluplusDll.dll")]
    public static unsafe extern bool DoSomethingToStruct(InputOutputStruct* s);

class CSharpWrapper {
    static void Main(string[] args)
    {
        InputOutputStruct s = new InputOutputStruct();
        unsafe {
            InputOutpustruct* sPtr = &s;
            DoSomethingToStruct(sPtr);
            s = *sPtr;
        }
    }
}

Ответы [ 2 ]

4 голосов
/ 06 декабря 2011

Мне кажется, что вы должны определить структуру как в управляемом, так и в неуправляемом коде.

Не верно.Это то, для чего был изобретен C ++ / CLI - значительно упростить взаимодействие с C ++ и .NET.

1 голос
/ 06 декабря 2011

но возможно ли, чтобы DLL возвращала структуру правильного формата в оболочку C #?

Я так не думаю, потому что вам всегда нужно определять структурына стороне C #.

Вот решение, которое может работать (никогда не тестировалось):

  • Присвойте каждой структуре, которой совместно используется уникальный идентификатор с обеих сторон (GUID, Macros)
  • Создать отражение для C ++, которое содержит информацию о типах, которые используются на стороне C # и C ++.Это можно сделать с помощью макросов.
  • Сравните структуры C ++ и C # при запуске, используя GUID, отражение и макросы.Вы также можете использовать sizeof для сравнения размеров в первую очередь.

  • Это может быть много работы
  • При работе на стороне C ++ вы все равно можете сделатьмного чего не так, когда вы не знаете о макросах
...