Выделение ссылки на IntPtr для BSTR * в C # - PullRequest
0 голосов
/ 10 ноября 2010

Я пытаюсь вызвать функцию, которая выделяет память для строки, а затем что-то делает со строкой.Вот базовый пример, который иллюстрирует проблему:

C ++:

    STDMETHODIMP CFunctionsCollection::Function2 (  
        BSTR leftString, BSTR rightString, BSTR * conString
    )
{
    int leftLen = lstrlen(leftString);
    int rightLen = lstrlen(rightString);

    *conString = new TCHAR[leftLen+rightLen+1];

    for (int i=0 ; i<leftLen ; ++i)
        (*conString)[i] = leftString[i];
    for (int i=0 ; i<rightLen ; ++i)
        (*conString)[leftLen+i] = rightString[i];
    (*conString)[leftLen+rightLen] = 0;

    return S_OK;
}

Следующий вызов из программы C ++ прекрасно работает:

BSTR leftString = SysAllocString(L"Left String");
BSTR rightString = SysAllocString(L"Right String");
BSTR conString;
hr = pFunctionsCollection->Function2 ( leftString, rightString, & conString);

Объявление C #:

Int32 Function2([In, MarshalAs(UnmanagedType.BStr)] String leftString,
                [In, MarshalAs(UnmanagedType.BStr)] String rightString,
                [In, Out] ref IntPtr conStr);

C # вызов:

try
{
    String leftString = "Left String"; 
    String rightString = "Right String";
    IntPtr outStr = IntPtr.Zero;
    pFunctionsCollection.Function2(leftString, rightString, ref outStr);
    String outString = Marshal.PtrToStringUni(outStr);
    Console.WriteLine("Out String = {0}", outString);
}
catch (Exception e)
{
    Console.WriteLine("Call to Function2 failed with {0}", e.Message);
}

Сбой программы с

Сбой вызова функции 2 с Недостаточно памяти для продолжения выполнения программы.

Кто-нибудь знает, как делать такие звонки из C #?

1 Ответ

1 голос
/ 01 апреля 2011

conString является BSTR и должен рассматриваться как таковой. Смотри http://msdn.microsoft.com/en-us/library/ms221069.aspx

  1. Вы должны использовать SysStringLen, чтобы получить длину BSTR
  2. Ваш последний параметр в C # должен быть строкой out, маршалированной как BSTR

    [In, Out, MarshalAs (UnmanagedType.BStr)] out строка conStr

  3. Вам необходимо выделить память для conStr с помощью SysAllocString или SysAllocStringLen

  4. Элемент списка

Вы не можете выделить память с помощью 'new' и привести ее к BSTR. BSTR предъявляют особые требования к управлению памятью и макету, которые вас не удовлетворяют. Вы должны всегда следовать этим правилам. Взаимодействие завершается ошибкой, поскольку ожидается, что вы следуете соглашениям для BSTR, но это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...