www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Getting the typeid of an object disguised under an interface

reply Tomer Filiba <tomerfiliba gmail.com> writes:
In continuation of an ancient thread: 
http://forum.dlang.org/post/k9gu6d$2glr$1 digitalmars.com

I wanted to do something like what Gor wanted, ended up with this:

Object interfaceToObject(I)(I obj) if (is(I == interface)) {
     import object;
     return cast(Object)(cast(void*)obj - 
((cast(Interface*)obj.__vptr[0]).offset));
}

writeln(interfaceToObject(ex.info))
// prints core.runtime.defaultTraceHandler.DefaultTraceInfo

By the way, the reason I need it is to get the actual callstack 
from the TraceInfo, so in reality it's much worse:

struct DefaultTraceInfo {
     int      numframes;
     void*[0] callstack;
}
auto traceInfo = 
cast(DefaultTraceInfo*)(cast(void*)(interfaceToObject(ex.info)) + 
(void*).sizeof * 2);

It would be really nice if TraceInfo exposed the callstack to the 
user. It only provides an opApply that converts to it string... 
adding a simple property such as

 property void*[] frames();

would be awesome.
Mar 28 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 28 March 2016 at 11:58:17 UTC, Tomer Filiba wrote:
 Object interfaceToObject(I)(I obj) if (is(I == interface)) {
     import object;
     return cast(Object)(cast(void*)obj - 
 ((cast(Interface*)obj.__vptr[0]).offset));
 }
eeek, plain `cast(Object) obj` works for this! You don't need all that other stuff.
 It would be really nice if TraceInfo exposed the callstack to 
 the user. It only provides an opApply that converts to it 
 string... adding a simple property such as
You could always call the backtrace function from the debug info if you are on Linux. http://man7.org/linux/man-pages/man3/backtrace.3.html That's what trace info used to do. (now it does it itself but same thing)
Mar 28 2016
parent reply Tomer Filiba <tomerfiliba gmail.com> writes:
On Monday, 28 March 2016 at 14:31:57 UTC, Adam D. Ruppe wrote:
 eeek, plain `cast(Object) obj` works for this! You don't need 
 all that other stuff.
cool! didn't know that. it makes sense now that i think of it.
 You could always call the backtrace function from the debug 
 info if you are on Linux.
yes, but it's used for logging exceptions. instead of doing the to-string conversion in place, we just keep the raw pointers and do addr2line on demand. so we're given an exception and need to extract the bt from it -tomer
Mar 28 2016
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 28 March 2016 at 17:40:15 UTC, Tomer Filiba wrote:
 yes, but it's used for logging exceptions. instead of doing the 
 to-string conversion in place, we just keep the raw pointers 
 and do addr2line on demand. so we're given an exception and 
 need to extract the bt from it
Perhaps you can set your own trace handler and either copy/paste code from druntime or just do your own backtrace() based thing: http://dpldocs.info/experimental-docs/core.runtime.Runtime.traceHandler.1.html Ugh, the druntime authors didn't actually document TraceHandler (it is listed as private, but that function obviously isn't). It is: alias Throwable.TraceInfo function( void* ptr ) TraceHandler; The thing it passes is typically null. So you construct your own class fitting the TraceInfo interface and this is called when an exception is built.
Mar 28 2016