Я использую Visual Studio 2013 и C ++ 11. Я хочу передать адрес объекта C ++ обратно C. Код C будет обрабатывать его как непрозрачный дескриптор; С никогда не будет ссылаться на это. Единственное использование будет передавать его обратно в C ++, где он снова будет использоваться как указатель на объект.
Я обнаружил, что если я создаю объект в C ++ и передаю его обратно в C, объект будет уничтожен, потому что он выходит из области видимости. В качестве обходного пути я создал глобальную переменную для хранения объекта, чтобы он не был уничтожен при возврате в C. Какова лучшая практика? Должен ли я использовать тип указателя с пересчетом, такой как shared_ptr
? Как? Мне не нравится идея кастинга size_t
или такой.
Ниже приводится попытка продемонстрировать вопрос. Код не сработает.
extern "C" _declspec(dllexport) void __stdcall SwbHttpListenW(const wchar_t *route, SwbHttpListen **listener)
{
*listener = &SwbHttpListen(route); // new will work but how about without new?
}
[Отредактировал код, чтобы повторно запросить решение, не используя new
.]
Как насчет выделения кучи объекта C ++ с помощью новый оператор, и получить его адрес с помощью амперсанда (&) оператор? Распределяя объект по куче, вы гарантируете, что он никогда не будет удален, пока вы не используете удалять оператор на нем, и адрес может быть сохранен / передан как int.
Простой пример:
int main() {
Person *a = new Person("Paul");
doSomething(a); //Passes the memory address of a to the function doSomething//...and once you're finished using the object, you have to:
delete a;
return 0;
}
Когда вы делаете такие вещи, это всегда будет грязно, то, как вы справитесь с этим, зависит от того, каким будет срок службы вашего объекта c ++, и, в меньшей степени, от того, как вы собираетесь от него избавиться в конец. Но ясно, что c ++ должен уничтожать, вы не можете заставить c сделать это.
Подобные вещи являются примером того, что глобальные объекты не обязательно плохая вещь — хотя, конечно, это означает, что вы не можете избавиться от них свободно. В качестве альтернативы, вы можете создать его динамически, используя new, но тогда вам понадобится расположение между c и c ++, чтобы оно было удалено в нужное время — вы можете получить глобальный указатель объекта или, возможно, c мог бы передать указатель обратно уничтожить его — это было бы самым лучшим решением.
Некоторые проблемы могут возникнуть, если используется какой-то автоматический сборщик мусора (это может быть в C ++). std::declare_reachable
, std::undeclare_reachable
может помочь
Иначе проблема действительно не в том, чтобы передать указатель на C. И вам нужно разработать какой-то способ для достижения правильных указателей на действительные объекты в местах, где это необходимо … 🙂