Получение буфера из указателя

#.net #pointers #intptr

#.net #указатели #intptr

Вопрос:

Это код, который я получил с ошибкой get the last в буфер, но я понятия не имею, как преобразовать IntPtr во что-то, что я мог бы прочитать… Я просто получаю длинное число.

 /// Return Type: void
///pErrorCode: ABS_DWORD*
///ppErrorMessage: ABS_CHAR**
        [System.Runtime.InteropServices.DllImportAttribute("bsapi.dll", EntryPoint = "ABSGetLastErrorInfo", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static extern void ABSGetLastErrorInfo(ref uint pErrorCode, ref System.IntPtr ppErrorMessage);
  

Это из руководства:

 void ABSGetLastErrorInfo(
OUT ABS_DWORD *pErrorCode
OUT const ABS_CHAR **ppErrorMessage
)
  

Описание извлекает дополнительную информацию о последней ошибке BSAPI, которая произошла в текущем потоке.

ppErrorMessage На выходе устанавливается так, чтобы указывать на буфер, содержащий строку с нулевым завершением и текстовое сообщение.

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

Буфером управляет BSAPI; не используйте ABSFree для его освобождения. Обратите внимание, что буфер действителен только до тех пор, пока в том же потоке не будет выполнен другой вызов BSAPI. После следующего вызова буфер может быть освобожден или повторно использован BSAPI. Если вам нужно запомнить сообщение, вы должны скопировать его в свой собственный буфер.

Ответ №1:

Определить как

  public static extern void ABSGetLastErrorInfo(ref uint pErrorCode, StringBuilder ppErrorMessage);
  

StringBuilder используется для выходных строк. Смотрите здесь.

Если строковый параметр может быть входным и / или выходным, тогда используйте систему.Тип StringBuilder. Тип StringBuilder — это полезный тип библиотеки классов, который помогает вам эффективно создавать строки, и он отлично подходит для передачи буферов собственным функциям, которые функции заполняют строковыми данными от вашего имени. После возврата вызова функции вам нужно только вызвать toString для объекта StringBuilder, чтобы получить объект String.


Обновить

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

 public static extern void ABSGetLastErrorInfo(ref uint pErrorCode, ref StringBuilder ppErrorMessage);
  

Комментарии:

1. когда я вызываю его следующим образом Dim Code Как UInteger Dim errorInfo Как StringBuilder = Ничего ABSGetLastErrorInfo(Code, errorInfo), приложение завершает работу без ошибок.

2. Нет, создайте новый stringbuilder и передайте его функции. После вызова stringbuilder должен вернуть вашу строку.

3. Те же результаты: (все еще сбой

4. Я действительно считаю, что это StringBuilder должно передаваться по ссылке. ref StringBuilder ppErrorMessage .

5. Если это не сработает, то сделайте это ref IntPtr ppErrorMessage , и когда вы получите значение обратно, вызовите Marshal.PtrToStringAnsi : msdn.microsoft.com/en-us/library/7b620dhe.aspx