none
Проблема с P/Invoke RRS feed

  • Вопрос

  • У меня есть dll, в которой реализован интерфейс для работы с движком распознавания речи. Она написана на C++. Проблема заключается в непонятном для меня поведении механизма P/Invoke. Инициализация движка проходит успешно. Но проблема появляется, когда я пытаюсь получить результат распознавания. Вот обертка в C#:

    [DllImport(@"C:\Users\__ParaPik__\Documents\Visual Studio 2010\Projects\Research Works\Debug\SRE.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
        public static extern string GetNextHyp();
    

    Когда я диктую короткие фразы, скажем, два-три слова, то все работает нормально. Но когда я диктую чуть больше, то сразу получаю AccessViolation. Причем если я использую эту dll в native приложении на C++, то никаких проблем нет, все работает замечательно.

    Помогите разобраться, в чем дело.

    30 июля 2011 г. 10:02

Ответы

  • Замена string на StringBuilder ничего не дала. Но я все-таки решил проблему. Похоже, что у P/Invoke есть какие-то ограничения на длины строк из unmanaged heap. Я просто заменил возвращаемый тип на byte*, а потом сам извлекал строку. При таком подходе никаких проблем не возникает. Спасибо всем за помощь при решении проблемы.
    • Помечено в качестве ответа __ParaPik__ 4 августа 2011 г. 4:58
    4 августа 2011 г. 4:56

Все ответы

  • А можете привести здесь c++ объявление функции GetNextHyp()? Сдаётся мне, что проблема в невозможности прямого использования .NET-типа "string". Могу предположить, что ф-я возвращает УКАЗАТЕЛЬ на буфер, содержимое которого нужно отдельным вызовом Marshal-функции преобразовывать в строку.
    1 августа 2011 г. 9:08
  • Да, конечно.

     

    const char * __stdcall GetNextHyp()
    {
    	EnterCriticalSection(&CSEC);
    	const char * _res = "";
    	if (SREHyps.size() != 0)	
    		_res = SREHyps[SREHyps.size() - 1].c_str();	
    	LeaveCriticalSection(&CSEC);
    	return _res;
    }
    

     

    //--------------------------------------------------------------
    Но интересно то, что даже такая функция дает сбой:

     

    EXPORT const char * __stdcall StrFunc()
    {
      char * _str = new char[2];
      _str[0] = 'A';
      _str[1] = '\0';
      return _str;
    }
    

     

    Хотя такой вариант работает нормально:

     

    EXPORT const char * __stdcall StrFunc()
    {
      return "It works great!!!";
    }
    


     


    1 августа 2011 г. 16:25
  • Попробуйте в качестве возвращаемого типа указать не string, а StringBulider.

    Также посмотрите статью на codeproject - Essential P/Invoke

    Возможно это вам поможет в решении проблемы.


    Для связи [mail]

    3 августа 2011 г. 10:40
  • Замена string на StringBuilder ничего не дала. Но я все-таки решил проблему. Похоже, что у P/Invoke есть какие-то ограничения на длины строк из unmanaged heap. Я просто заменил возвращаемый тип на byte*, а потом сам извлекал строку. При таком подходе никаких проблем не возникает. Спасибо всем за помощь при решении проблемы.
    • Помечено в качестве ответа __ParaPik__ 4 августа 2011 г. 4:58
    4 августа 2011 г. 4:56