Могу ли я использовать C# 7.2 в модификаторе вместо IntPtr? - PullRequest
0 голосов
/ 12 апреля 2020

Я использую эту собственную DLL, которая экспортирует 2 функции:

int str_get(char** strPtr); // to allocate and return a string
void str_free(char* str); // to free the above string

Я собираю эти функции в C# как:

int str_get(out IntPtr str);
void str_free(IntPtr str);

... затем использую Marshal.PtrToStringAnsi для получить строку. Это работает, как и ожидалось.

Я также могу упорядочить функцию "get" следующим образом:

int str_get(out string str)

Таким образом, я могу получить строку напрямую, без использования Marshal. Однако я не могу понять, как вызвать функцию «free» в этом случае. Я думал, что мне нужно распределить его по-другому, возможно, используя модификатор in в C# 7.2 либо как in string, либо как in char. Это не работает в любом случае, или я не знаю, как это назвать.

Итак, я должен спросить: это вообще возможно? И если да, то как?

1 Ответ

1 голос
/ 12 апреля 2020

Нет, это не будет работать. Когда вы выполняете маршалинг между char* и string, маршалер выделяет новый объект управляемой строки или неуправляемую память и копирует данные поверх.

Соответствующая подпись p / invoke для void str_free(char* str); будет просто void str_free(string str), но указатель char*, переданный str_free, не будет тем же, что был возвращен str_get. Это указывало бы на другую копию данных, которая была распределена CLR, а не на собственную DLL, и бесплатная почти наверняка потерпела бы неудачу.

...