2010-12-16 2 views
1

У меня проблема с p/invoke из управляемого неуправляемого кода. См. Мой оригинал post at the MSDN forum (как краткое изложение видно ниже в этом сообщении). Прежде чем продолжить, я просто хочу объяснить несколько вещей: у меня есть сборка оберток в сети 3.5, которая делает фактический переход к неуправляемому коду. Затем у меня есть консольное «хост-приложение», которое использует сборку обертки.pInvoke, .net 4 vs 3.5

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

  • хост-приложение: 4,0, обертка сборки: 3,5 -> работает приложение
  • узла: 3,5, обертка сборки: 3,5 -> броски AccessViolationException

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

Краткое резюме на почтовом ящике MSDN, на которое я ссылался. У меня есть этот беспорядочный p/Invoke, который мне нужно решить. Декларация 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); 

Где РТВА означают, что каждый аргумент является указателем структуры на массив произвольной длины. Структуры в основном содержат строки, парные, char и короткие. Во всяком случае, я в конечном итоге с этим 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 

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

+0

Пожалуйста, отредактируйте ваш вопрос здесь, чтобы включить суть сообщения MSDN. Вопросы о SO должны стоять самостоятельно, без необходимости читать сообщение в другом месте. – 2010-12-16 16:57:51

+0

также, мы стараемся придерживаться точки здесь, и опускаем «Привет» и «Спасибо». – 2010-12-16 17:05:01

ответ

0

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

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

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

Смежные вопросы