Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Can I use tango's gc when I link some c++ program with D?

Moderators: larsivi kris

Posted: 09/22/07 13:58:01 Modified: 09/22/07 14:01:31

Is it safe if I override the operator new and operator delete of some C++ class to call gc_malloc and gc_free? I won't override global operator new and operator delete.

Author Message

Posted: 09/22/07 13:59:53 -- Modified: 09/26/07 11:30:27 by
Yang Bo -- Modified 2 Times

Is it needed to put main() in D in order to initialize tango's runtime? And, what is the easiest way to let dsss work with bjam?

Posted: 09/24/07 15:55:35

Almost. By default, Tango will only scan the threads that it is aware of, those being the main thread and any threads created via the tango.core.Thread object. If you call gc_malloc from another thread (say one created in C++ via _beginthread) then you need to tell Tango about this thread if you plan for it to maintain references to GCed data. At the moment, there is no way to do this. But I've been planning to add one. I'll look into it today.

Posted: 09/24/07 16:03:26

To initialize Tango's runtime, you can use these functions:

extern (C) bool  rt_init( void delegate( Exception ) dg = null );
extern (C) bool  rt_term( void delegate( Exception ) dg = null );

If you want to call them directly from C++, you should be able to redefine them like so:

struct Dg{ void *a, *b; Dg() : a( 0 ), b( 0 ) {} };

extern "C" char rt_init(Dg dg = Dg());
extern "C" char rt_term(Dg dg = Dg());

and don't pass any parameters in. If they succeed, the return value should be nonzero.

Posted: 09/26/07 11:33:24

Thank you.

Posted: 09/29/07 11:36:53 -- Modified: 09/29/07 11:38:47 by
Yang Bo -- Modified 2 Times

Does these code cause memory leak? Will the destructor of the vector be called?

// C++
#include <vector>

namespace tango { namespace core { namespace Memory {
  extern "C" void gc_free(void* p);
  extern "C" void* gc_malloc(std::size_t sz, boost::uint32_t ba = 0);
} } }

struct my_cpp_object {
  void* operator new(std::size_t sz) {
    return tango::core::Memory::gc_malloc(sz);
  }
  void operator delete(void* p) {
    tango::core::Memory::gc_free(p);
  }
  std::vector<char> v;
  my_cpp_object() : v(100) {
  }
};

extern "C" void new_cpp_object() {
  new my_cpp_object;
}
// D
extern (C) void new_cpp_object();

int main() {
  for(int i = 0; i < 1000000; i++) {
    new_cpp_object();
  }
  return 0;
}

Posted: 10/05/07 14:36:19

I just added two new routines:

extern (C) void thread_attachThis();
extern (C) void thread_detachThis();

They will register and unregister the calling thread for use with GCed memory, etc. Please let me know if this works for you.

Posted: 10/12/07 15:49:52

It is not a problem for me. I start all thread in D.