Импорт c ++ dll в проект c # - PullRequest
4 голосов
/ 04 марта 2011

Я импортирую некоторые c ++ dll в проект c #, я использую Visual Studio 2010. Мне удалось импортировать функцию, использующую встроенный тип, однако я получаю сообщение об ошибке, когда пытаюсь разобраться со структурой. Это простой пример:

код C ++

typedef long int TDate;

typedef struct _TMDYDate
{
    long month;                         /* In range [1,12] */
    long day;                           /* In range [1-31] */
    long year;                          /* In range [1600-] */
} TMonthDayYear;

int JpmcdsDateToMDY
    (TDate date,                        /* (I) TDate format */
     TMonthDayYear *mdyDate);

и я перевел на c # как:

   [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct TMonthDayYear {
    public int month;
    public int day;
    public int year;
}

public partial class NativeMethods {

    [System.Runtime.InteropServices.DllImportAttribute("MyDll.dll", EntryPoint="JpmcdsDateToMDY")]
public static extern  int JpmcdsDateToMDY(int date, ref TMonthDayYear mdyDate) ;

}

когда я пытаюсь запустить функцию в моей тестовой программе, я получаю эту ошибку:

Необработанное исключение: System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто указывает на то, что другая память повреждена. at CsharpWrapper.NativeMethods.JpmcdsDateToMDY (Int32 date, TMonthDayYear & mdy Date)

Структура объявлена ​​в стеке, и я подумал (возможно), что это проблема, но я все еще получаю ту же ошибку, даже если я изменил TMonthDayYear на класс.

Что я делаю не так?

Спасибо за помощь.

Ответы [ 4 ]

3 голосов
/ 04 марта 2011

Вы должны использовать свойство CallingConvention в атрибуте [DllImport], это Cdecl, поскольку вы не использовали __stdcall в объявлении нативной функции.Хотя это не так, это не лучшее объяснение для AV.Вам нужно отладить код на C, AV предполагает наличие ошибки указателя.Project + Properties, Debug, отметьте «Включить отладку неуправляемого кода» и установите точку останова для функции C.

Честно говоря, преобразование даты, подобное этому, должно быть написано на чистом C #.

0 голосов
/ 04 марта 2011

Если вы знакомый пользователь в c ++, вы, вероятно, знакомы с указателями, обращающимися непосредственно к памяти. Ваша ошибка выглядит как проблема, связанная с защитой чтения / записи памяти.

Это запрещено стандартной природой C #, и вы должны перевести компилятор в небезопасный режим.

Если вы используете небезопасный код в c #, вы должны перевести код в небезопасный режим.

   unsafe
   {
     // unsafe things
   }

   unsafe class Class1 {}

   static unsafe void someMethod ( int* cpi, int lngth) {...} 

Вам также необходимо проверить конфигурацию проекта ( Build -tab) и установить флажок " Разрешить небезопасный код ".

Я прошу прощения, если прокручивал слишком очевидную информацию. Я также констатирую, что этот комментарий имеет смысл только в том случае, если C # будет обращаться к памяти.

0 голосов
/ 04 марта 2011

Может быть или не быть связанным, но вам нужно [OutAttribute] в параметре mdyDate для записи в него.

0 голосов
/ 04 марта 2011

TDate тип в нативном коде - long int, но в управляемом коде он представлен как int32 вместо int64.

...