2013-06-15 9 views
9

Ich habe eine C-Bibliothek, die ich nach C++ portiere, die von Hand reference-counted Strukturen verwendet. Ich habe überlegt, shared_ptr zu verwenden, um die Referenzzählung automatisch zu verarbeiten, aber ich möchte auch die C-API beibehalten. Die alten Signaturen in etwa so aussehen:Verwendung von shared_ptr in C-Schnittstellen?

Object* object_create(void); 
Object* object_retain(Object* o); 
void object_release(Object* o); 

Wenn ich shared_ptr verwenden, ist es eine Möglichkeit, um effektiv dieses Handbuch Referenzzählung in einer C-API aussetzen?

+1

Nur um zu klären; Sie wollen ein shared_ptr, um einen rohen Pointer zu erhalten, der von 'object_create' erhalten wurde, und ihn' object_release' zum relevanten Zeitpunkt aufrufen? –

+0

@OliCharlesworth Nein, ich erhalte "Objekt" als eine Klasse (anstelle einer Struktur) in C++, und ich verwende 'shared_ptr' innerhalb des C++ Codes. Ich bin daran interessiert, ob es möglich ist, einen rohen Zeiger von einem shared_ptr zu bekommen und ihn dann irgendwie mit dem Refcount von shared_ptr arbeiten zu lassen. –

+2

Sie könnten besser mit [Boost.intrusive_ptr] (http://www.boost.org/doc/libs/1_53_0/libs/smart_ptr/ intrusive_ptr.html). – Angew

Antwort

5

Das Problem mit shared_ptr, wie Sie bereits herausgefunden haben, ist, dass Sie die Referenzzahl nicht ändern können, außer durch das Konstruieren oder Zerstören von Instanzen. Also nein, es gibt keine Möglichkeit, das zum Laufen zu bringen, außer indem man einen shared_ptr um jeden konstruierten Object herum hält, bis sein Referenzzähler auf Null fällt, aber dieses Recht zu machen bedeutet, viel vom Referenzzählen zu wiederholen, so dass du sehr wenig gewinnst.

Vielleicht boost::intrusive_ptr ist eine bessere Option.

1

Sie können std::shared_ptr::get verwenden, um den Wert Ihres Zeigers in Ihrem object_create abzurufen.

Ich bin mir nicht sicher, ob Sie object_retain oder object_release pflegen sollten, da es bereits automatisch von der shared_ptr gehandhabt wird.

Möchten Sie, dass Ihre Bibliothek von C-Code verwendet wird? Wenn ja, wie @Angew in seinem Kommentar darauf hingewiesen hat, werfen Sie einen Blick auf Boost.intrusive_ptr, es scheint die beste Wahl zu sein.

Wenn Sie davon ausgehen können, dass in C geschriebener Client-Code die C-Bibliothek verwendet (was meiner Meinung nach sinnvoll ist), dann können Sie diese Funktionen komplett löschen und alle intern behandeln. Sie können einen rohen Zeiger für die Kompatibilität mit CAPI bereitstellen, wenn Sie benötigen, aber die gesamte Lebensdauerverwaltung kann automatisch mit shared_ptr behandelt werden.

+0

Die Referenzzählung wird nicht automatisch auf der C-Seite gehalten. Wenn das letzte "shared_ptr" zu einem "Object" zerstört wird, aber noch ein "Object *" darauf zeigt, wird das Objekt zerstört und der C-Zeiger bleibt hängen. –

+0

Wahr, ich dachte an einen rohen Zeiger, der als Betrachter des Objekts verwendet wurde, unter der Annahme, dass 'shared_ptr' die Lebensdauer des Objekts behandeln würde. – Uflex

Verwandte Themen