www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Does RTTI and exceptions work in dlls on windows?

reply "MrSmith" <mrsmith33 yandex.ru> writes:
I've got little test here 
https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.

I have one application and two dlls. Application loads both dlls, 
calls their factory functions and then passes each IModule 
instance that it got from factories to those modules.

Modules then try to cast those IModule refs back to their real 
interfaces (ISharedModule1) but i am getting null there.

A have found a workaround for this by returning a void* pointer 
to real interface and it back when needed.

Another, and more major issue is, that when exception is thrown 
application fail immediately.

Is it broken on windows, or it is me doing it wrong?
Nov 24 2014
next sibling parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 24.11.2014 19:20, MrSmith wrote:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both dlls, calls
 their factory functions and then passes each IModule instance that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.
The different DLLs have different copies of the RTTI for the classes (you could not link them separately otherwise). Looking for base classes or derived classes only compares RTTI pointers, so it doesn't find the target class of a cast in the hierarchy inside another DLL.
 A have found a workaround for this by returning a void* pointer to real
 interface and it back when needed.
Another workaround for a limited number of classes would be to add member functions 'ISharedModule1 toSharedModule1() { return null; }' in IModule and override these 'ISharedModule1 toSharedModule1() { return this; }' in the appropriate class.
 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
I haven't tried in a while but I think it should work on Win32, but probably does not on Win64.
Nov 24 2014
next sibling parent "MrSmith" <mrsmith33 yandex.ru> writes:
On Monday, 24 November 2014 at 20:56:29 UTC, Rainer Schuetze 
wrote:
 On 24.11.2014 19:20, MrSmith wrote:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both 
 dlls, calls
 their factory functions and then passes each IModule instance 
 that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.
The different DLLs have different copies of the RTTI for the classes (you could not link them separately otherwise). Looking for base classes or derived classes only compares RTTI pointers, so it doesn't find the target class of a cast in the hierarchy inside another DLL.
 A have found a workaround for this by returning a void* 
 pointer to real
 interface and it back when needed.
Another workaround for a limited number of classes would be to add member functions 'ISharedModule1 toSharedModule1() { return null; }' in IModule and override these 'ISharedModule1 toSharedModule1() { return this; }' in the appropriate class.
 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
I haven't tried in a while but I think it should work on Win32, but probably does not on Win64.
I thought it will work at least for interfaces. Any way, this is workaroundable, but exceptions must be there at least.
Nov 24 2014
prev sibling parent reply "Kagamin" <spam here.lot> writes:
On Monday, 24 November 2014 at 20:56:29 UTC, Rainer Schuetze 
wrote:
 The different DLLs have different copies of the RTTI for the 
 classes (you could not link them separately otherwise). Looking 
 for base classes or derived classes only compares RTTI 
 pointers, so it doesn't find the target class of a cast in the 
 hierarchy inside another DLL.
Maybe we can have a function, which will search the typeinfo based on type name, like C++ does it?
Nov 25 2014
next sibling parent "MrSmith" <mrsmith33 yandex.ru> writes:
On Tuesday, 25 November 2014 at 10:02:00 UTC, Kagamin wrote:
 On Monday, 24 November 2014 at 20:56:29 UTC, Rainer Schuetze 
 wrote:
 The different DLLs have different copies of the RTTI for the 
 classes (you could not link them separately otherwise). 
 Looking for base classes or derived classes only compares RTTI 
 pointers, so it doesn't find the target class of a cast in the 
 hierarchy inside another DLL.
Maybe we can have a function, which will search the typeinfo based on type name, like C++ does it?
I was sure that when dll is loaded, runtimes will merge (hook) and all type info is shared between dll and application.
Nov 25 2014
prev sibling parent reply Martin Nowak <code+news.digitalmars dawg.eu> writes:
On 11/25/2014 11:01 AM, Kagamin wrote:
 Maybe we can have a function, which will search the typeinfo based on
 type name, like C++ does it?
No! https://issues.dlang.org/show_bug.cgi?id=7020#c2
Nov 27 2014
parent "Kagamin" <spam here.lot> writes:
On Thursday, 27 November 2014 at 11:21:23 UTC, Martin Nowak wrote:
 No!
 https://issues.dlang.org/show_bug.cgi?id=7020#c2
If you want interfaces to be unique, you'll have whole new dlls containing only interface definitions and probably nothing else, just for the sake of uniqueness (things like this happen in .net). And you still have to deal with templates.
Nov 28 2014
prev sibling next sibling parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
Am 24.11.2014 19:20, schrieb MrSmith:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both dlls, calls
 their factory functions and then passes each IModule instance that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.

 A have found a workaround for this by returning a void* pointer to real
 interface and it back when needed.

 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
Dlls are generally broken on windows. If you hack around in druntime (e.g. the casting routines) you can get it to work to some degree, but you are going to be happier if you just stay away from it.
Nov 25 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Tuesday, 25 November 2014 at 18:39:56 UTC, Benjamin Thaut 
wrote:
 Am 24.11.2014 19:20, schrieb MrSmith:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both 
 dlls, calls
 their factory functions and then passes each IModule instance 
 that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.

 A have found a workaround for this by returning a void* 
 pointer to real
 interface and it back when needed.

 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
Dlls are generally broken on windows. If you hack around in druntime (e.g. the casting routines) you can get it to work to some degree, but you are going to be happier if you just stay away from it.
Is there a bugzilla issue for this? And what is the status of windows dlls?
Nov 25 2014
next sibling parent Benjamin Thaut <code benjamin-thaut.de> writes:
Am 25.11.2014 21:46, schrieb MrSmith:
 On Tuesday, 25 November 2014 at 18:39:56 UTC, Benjamin Thaut wrote:
 Am 24.11.2014 19:20, schrieb MrSmith:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.



 I have one application and two dlls. Application loads both dlls, calls
 their factory functions and then passes each IModule instance that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.

 A have found a workaround for this by returning a void* pointer to real
 interface and it back when needed.

 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
Dlls are generally broken on windows. If you hack around in druntime (e.g. the casting routines) you can get it to work to some degree, but you are going to be happier if you just stay away from it.
Is there a bugzilla issue for this? And what is the status of windows dlls?
Yes there is: https://issues.dlang.org/show_bug.cgi?id=9816 Also: http://wiki.dlang.org/DIP45 I'm currently working on it, but I can not promise anything. Also its unclear how long its going to take to get it merged once its actually working. Kind Regards Benjamin Thaut
Nov 25 2014
prev sibling parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
Am 25.11.2014 21:46, schrieb MrSmith:
 Is there a bugzilla issue for this? And what is the status of windows dlls?
If you want a bit more dll support right now, I suggest that you take a look at these changes and merge them into your own version of druntime: https://github.com/Ingrater/druntime/commit/7e54eac91dd34810913cfe740e709b18cbbc00d6 Kind Regards Benjamin Thaut
Nov 25 2014
parent "MrSmith" <mrsmith33 yandex.ru> writes:
On Wednesday, 26 November 2014 at 07:46:12 UTC, Benjamin Thaut 
wrote:
 Am 25.11.2014 21:46, schrieb MrSmith:
 Is there a bugzilla issue for this? And what is the status of 
 windows dlls?
If you want a bit more dll support right now, I suggest that you take a look at these changes and merge them into your own version of druntime: https://github.com/Ingrater/druntime/commit/7e54eac91dd34810913cfe740e709b18cbbc00d6 Kind Regards Benjamin Thaut
Thank you very much!
Nov 26 2014
prev sibling parent reply Martin Nowak <code+news.digitalmars dawg.eu> writes:
On 11/24/2014 07:20 PM, MrSmith wrote:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both dlls, calls
 their factory functions and then passes each IModule instance that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.

 A have found a workaround for this by returning a void* pointer to real
 interface and it back when needed.

 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
On Windows we currently only support static linkage of phobos and druntime. DLLs do work as long as each one is isolated, once you start exchanging data across DLL boundaries you run in ODR issues. We need to make phobos itself a DLL to solve this, but that's quite a lot of work.
Nov 27 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Thursday, 27 November 2014 at 11:24:45 UTC, Martin Nowak wrote:
 On 11/24/2014 07:20 PM, MrSmith wrote:
 I've got little test here
 https://gist.github.com/MrSmith33/8750dd43c0843d45ccf8#file-sharedmodule2-d-L17-L29.


 I have one application and two dlls. Application loads both 
 dlls, calls
 their factory functions and then passes each IModule instance 
 that it
 got from factories to those modules.

 Modules then try to cast those IModule refs back to their real
 interfaces (ISharedModule1) but i am getting null there.

 A have found a workaround for this by returning a void* 
 pointer to real
 interface and it back when needed.

 Another, and more major issue is, that when exception is thrown
 application fail immediately.

 Is it broken on windows, or it is me doing it wrong?
On Windows we currently only support static linkage of phobos and druntime. DLLs do work as long as each one is isolated, once you start exchanging data across DLL boundaries you run in ODR issues. We need to make phobos itself a DLL to solve this, but that's quite a lot of work.
Can you suggest a good way to design mod system? Where each mod can depend on others and use their real functionality. All mods should be in form of dlls. Another question is: What dll features are currently supported on linux and what they should be idealy? How do i use them?
Nov 27 2014
parent reply "Martin Nowak" <code dawg.eu> writes:
On Thursday, 27 November 2014 at 21:52:27 UTC, MrSmith wrote:
 Can you suggest a good way to design mod system? Where each mod 
 can depend on others and use their real functionality. All mods 
 should be in form of dlls.
No DLL per module, just releasing a complete Phobos.DLL. If you want to ship a smaller Phobos.dll , build one yourself.
 Another question is: What dll features are currently supported 
 on linux and what they should be idealy? How do i use them?
Shared library support on Linux is feature complete (we're still lacking a high level wrapper). You can compile libraries using -fPIC -shared -defaultlib=libphobos2.so for the libs and -defaultlib=libphobos2.so for the application. https://github.com/D-Programming-Language/druntime/pull/617
Nov 29 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Saturday, 29 November 2014 at 13:52:11 UTC, Martin Nowak wrote:
 On Thursday, 27 November 2014 at 21:52:27 UTC, MrSmith wrote:
 Can you suggest a good way to design mod system? Where each 
 mod can depend on others and use their real functionality. All 
 mods should be in form of dlls.
No DLL per module, just releasing a complete Phobos.DLL. If you want to ship a smaller Phobos.dll , build one yourself.
I meant modifications, not modules here. Will it work if i have an interface and implementation of each modification in a separate shared library? How other modifications can depend on that interface? Should i simply add it to import path while compiling or i need to compile it too? This will cause a duplication of interface. On Friday, 28 November 2014 at 12:56:10 UTC, Kagamin wrote:
 On Thursday, 27 November 2014 at 11:21:23 UTC, Martin Nowak 
 wrote:
 No!
 https://issues.dlang.org/show_bug.cgi?id=7020#c2
If you want interfaces to be unique, you'll have whole new dlls containing only interface definitions and probably nothing else, just for the sake of uniqueness (things like this happen in .net). And you still have to deal with templates.
Can i compile it in the same dll with its implementation?
Dec 01 2014
parent reply "Kagamin" <spam here.lot> writes:
On Monday, 1 December 2014 at 18:35:28 UTC, MrSmith wrote:
 Can i compile it in the same dll with its implementation?
Yes, you can have all implementations in the same dll, interface will only have to be directly accessible to all code seeing it.
Dec 02 2014
parent reply "MrSmith" <mrsmith33 yandex.ru> writes:
On Tuesday, 2 December 2014 at 10:48:16 UTC, Kagamin wrote:
 On Monday, 1 December 2014 at 18:35:28 UTC, MrSmith wrote:
 Can i compile it in the same dll with its implementation?
Yes, you can have all implementations in the same dll, interface will only have to be directly accessible to all code seeing it.
Can i have interface compiled only in one dll, and others dlls that use this one will not have it compiled, only import it?
Dec 02 2014
next sibling parent "Kagamin" <spam here.lot> writes:
yes
Dec 03 2014
prev sibling parent Martin Nowak <code+news.digitalmars dawg.eu> writes:
On 12/02/2014 11:22 PM, MrSmith wrote:
 Can i have interface compiled only in one dll, and others dlls that use
 this one will not have it compiled, only import it?
Yes, you'd need to link against the dll containing the interfaces. In fact you could link against your executable too, but that's a bit ugly.
Dec 03 2014