Можем ли мы создать строковый объект C ++ из указателя на символ, где операции над строковым объектом отражаются на исходном указателе на символ? - PullRequest
0 голосов
/ 08 июля 2019

Я пытался использовать богатые методы класса C ++ (find_first_of, replace) для некоторой обработки строки для задачи.

И я создал файл обертки вокруг вышеупомянутого кода, где он может быть включен в исходные файлы 'C' и получить функциональность.

strUtils.h

#ifdef __cplusplus
extern "C" {
#endif

void doTheStringWork(char *inStr, unsigned beginLoc);

#ifdef __cplusplus
}
#endif

strUtils.cpp

#include "strUtils.h"
/*some standard includes here*/

void doTheStringWork(char *inStr, unsigned beginLoc) {
    std::string inStr_s(inStr);

    /* Doing some processing with the string object inStr_s*/  
    /* .......*/
    /* Done */

    return;  

}

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

Проблема в том, что мне нужно вернуть изменения, сделанные функцией doTheStringWork, на место вызывающего абонента.Вы можете сказать, взять значение .c_str() в качестве возврата из функции или получить копию каким-либо образом.Этот подход работает хорошо, но для моих задач он становится очень медленным, поскольку строка может быть слишком длинной, и мне может потребоваться ее рекурсивная обработка.

Другими словами: можем ли мы создать строковый объект вокруг указателя на символ, гдеЯ могу использовать все строковые функции, и указатель на символ отражает все эти изменения.Если такого нельзя добиться с помощью стандартной библиотеки, может кто-нибудь предложить подход, как мне достичь своей цели здесь.

1 Ответ

1 голос
/ 08 июля 2019

Лучшее решение - сбросить C, использовать C ++ и уйти от всего беспорядка. Но так как вы, вероятно, не можете этого сделать, следующим лучшим решением будет создание собственной видимой структуры C и некоторых видимых функций C (в основном PIMPL), определите их в исходном коде C ++ (чтобы вы получили преимущества std::string) и использовали их из C. Как то так

В strUtils.h заголовок:

#ifdef __cplusplus
extern "C" {
#endif
typedef struct cpp_string cpp_string;

cpp_string *cpp_string_create(const char *txt, int size);
void cpp_string_free(cpp_string *);
cpp_string *cpp_string_add(cpp_string *, cpp_string *);
... // all operations you need

#ifdef __cplusplus
}
#endif

В источнике C ++ (strUtils.cpp):

#include <string>
struct cpp_string {
  std::string str;
  cpp_string(std::string str): str(std::move(str)) { }
};
extern "C" cpp_string *cpp_string_create(const char *txt, int size)
{
  return new cpp_string{ std::string{ txt, (size_t)size } };
}

// fill operations here
// since this is C++ file, just use std::string without copying

Теперь, когда вы хотите использовать его, вы делаете что-то вроде этого:

int main()
{
    cpp_string *s = cpp_string_create("qwerty", 6);
    // do something with s

    // dont forget to free s
    cpp_string_free(s);

    return 0;
}

Это позволяет обойти всю память can-i-overwrite-кто-то-эльзес (нет, вы не можете, если вы не хотите иметь странные, странные проблемы), создавая свои собственные данные.

...