2017-02-11 2 views
1

Имея встроенную функцию, которая возвращает строку (как char *) по параметру, что было бы лучшим вариантом между предварительным распределением char * через управляемый код и передачей его параметром и выделяя char * из внутреннего кода, а затем отпустите его из C#?Как вывести строку из собственного кода

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

В качестве бонуса, я хотел бы знать, как я должен выделить переменную char * из C# в первом случае (используя класс Marshal или с простым новым или с StringBuilder, как я часто вижу в других ответах?) И как я должен удалить указатель, если вместо этого я создаю переменную char * из внутреннего кода во втором случае.

+0

Удалите оригинал, пожалуйста. Я действительно отмечен для удаления вчера, кто-то, должно быть, восстановил его! Также у оригинала ответа не было, только один комментарий – sebas

+0

@Flexo: с тех пор обманщик был удален, и этот вопрос, хотя и несколько «мягкий», кажется, по-теме и имеет достойный ответ. Не могли бы вы рассмотреть возможность его возобновления? –

ответ

2

Обычно не рекомендуется возвращать char* из функции C и ожидать, что он будет выделен вызывающим абонентом. Вызывающий может не делать этого (правильно или вообще) и, таким образом, будет утечка памяти. Один из распространенных способов, чтобы избежать этого (как используется OpenGL, OpenCL и другие библиотеки я видел), чтобы объявить прототип как:

int GetString(char* str, int* len);

с реализацией так:

int GetString(char* str, int* len) 
{ 
    if (str == NULL) 
    { 
     len = internal_get_string_length(); 
     return 0; // No errors 
    } 
    else 
    { 
     if (len <= internal_get_string_length()) 
      return -1; // not enough space in str 
     char* internal_str = internal_get_string_ptr(); 
     strcpy(str, internal_str); 
     return 0; 
    } 
} 

В документации будет указано, что если str равно NULL, длина возвращаемой строки возвращается в len. В противном случае указатель str должен содержать как можно больше символов. Чтобы использовать его, пользователь дважды вызывает функцию, один раз с NULL для str и int для len, затем снова с выделенным массивом символов, длиной len. Возможно, прототип для P/вызова этой функции:

// Declaration 
[DllImport("myDll.dll")] 
int GetString(StringBuilder sb, ref int len); 

// Usage 
int length; 
GetString(null, length); 
var sb = new StringBuilder(length); // Set capacity 
GetString(sb, length); 
Console.WriteLine(sb.ToString()); // Do stuff with C# string 

Надеюсь, что это поможет!

+0

немного неловко, но, по крайней мере, у меня есть лучшее понимание сейчас – sebas