pInvoke, .net 4 против 3,5 - PullRequest
       24

pInvoke, .net 4 против 3,5

1 голос
/ 16 декабря 2010

У меня проблема с p / invoke из управляемого в неуправляемый код. См. Мой оригинальный пост на форуме MSDN (краткое изложение приведено ниже в этом посте). Прежде чем продолжить, я просто хочу объяснить пару вещей: у меня есть сборка оболочки в сети 3.5, которая фактически взаимодействует с неуправляемым кодом. Тогда у меня есть консоль "хост-приложение", которая использует сборку оболочки.

Решение, которое я нашел (я ссылаюсь на мой пост MSDN), работает, когда хост-приложение использует .net 4, но не работает при изменении хост-приложения на .net 3.5. При изменении я получаю AccessViolationException.

  • хост-приложение: 4.0, сборка оболочки: 3.5 -> работает
  • хост-приложение: 3.5, сборка оболочки: 3.5 -> броски AccessViolationException

Кто-нибудь знает, почему я получаю AccessViolationException? Самое главное, как мне заставить его работать с .net 3.5?

Краткое описание сообщения MSDN, на которое я ссылался. У меня есть этот грязный п / инвокир, который мне нужно решить. Объявление C выглядит так:

long TBAPI TbeAndring (short, 
            short,
            PTB_PU,
            PTB_ANDRING_INFO,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK,
            PTB_PARAMS,
            PTB_PREMIE_NIVA_INFO,
            PTB_PREMIE,
            PTB_FORMAN_INFO,
            PTB_FORMAN,
            PTB_FUNK);

Где PTB означает, что каждый аргумент является структурным указателем на массив произвольной длины. Структуры в основном содержат строки, пары, символы и короткие. Во всяком случае, я закончил с этим оператором DllImport:

<DllImport(NativeLibraryName, CallingConvention:=CallingConvention.StdCall, CharSet:=CharSet.Ansi, SetLastError:=True)>
  Public Shared Function TbeAndring(ByVal sAntMoment As Short, _
                   ByVal sAntPU As Short, _
                   <[In]()> ByVal atbpu As PTB_PU(), _
                   <[In]()> ByVal atbandringinfo() As PTB_ANDRING_INFO, _
                   <[In]()> ByVal atbparamsEfter() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoEfter() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieEfter() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoEfter() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanEfter() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkEfter() As PTB_FUNK, _
                   <[In]()> ByVal atbparamsFore() As PTB_PARAMS, _
                   <[In]()> ByVal aNivaInfoFore() As PTB_PREMIE_NIVA_INFO, _
                   <[In](), Out()> ByVal atbpremieFore() As PTB_PREMIE, _
                   <[In]()> ByVal atbFormanInfoFore() As PTB_FORMAN_INFO, _
                   <[In](), Out()> ByVal atbFormanFore() As PTB_FORMAN, _
                   <[In](), Out()> ByVal atbfunkFore() As PTB_FUNK) As Int32
  End Function

Как видите, некоторые аргументы также изменяются неуправляемым кодом.

1 Ответ

0 голосов
/ 16 декабря 2010

Я не знаю, является ли это единственной причиной AccessViolationException, но я видел, что это исключение происходит из неуправляемого кода, который выполнялся с поврежденной кучей библиотеки времени выполнения C.В частности, некоторая память, которая должна была содержать действительный указатель, стала содержать мусор: при разыменовании она указывала на несуществующую память.

Если у вас есть проблема, подобная этой, то изменение в версии .NET может простопереместили проблему так, что проблема была замечена в .NET 3.5, но еще не пока не была замечена в .NET 4.0.

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

...