www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Dynamic D Library

reply teo <teo.ubuntu yahoo.com> writes:
One major problem is the D's inability to create dynamic libraries. D is a
great language, but without that ability it can only be used for small
programs, tools, etc. and never in production.

The D Runtime is a step forward, because it faces that problem. I noticed
following:

extern (C) void* rt_loadLibrary( in char[] name );
extern (C) bool rt_unloadLibrary( void* ptr );

/**

 * Locates a dynamic library with the supplied library name and dynamically

 * loads it into the caller's address space.  If the library contains a D

 * runtime it will be integrated with the current runtime.

 *

 * Params:

 *  name = The name of the dynamic library to load.

 *

 * Returns:

 *  A reference to the library or null on error.

 */

static void* loadLibrary( in char[] name )

{

    return rt_loadLibrary( name );

}



/**

 * Unloads the dynamic library referenced by p.  If this library contains a

 * D runtime then any necessary finalization or cleanup of that runtime

 * will be performed.

 *

 * Params:

 *  p = A reference to the library to unload.

 */

static bool unloadLibrary( void* p )

{

    return rt_unloadLibrary( p );

}


However “If the library contains a D
 runtime it will be integrated with the current runtime.
” Is this really needed? If the intention is to replace C/C++ some day, why not
just provide a dynamic D library? (like in this project:
http://www.dsource.org/projects/ddl/) It can contain only compiled D code
accompanied with meta-data like platform, version, etc. and be used only by D
programs. No runtime is needed within the DDL. When the DDL is loaded it will
be managed by the same GC which manages the program itself. Even Phobos can be
a DDL.

Maybe I am missing something and that's why I would like to hear your opinion.
Jul 15 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jul 16, 2009 at 2:12 AM, teo<teo.ubuntu yahoo.com> wrote:
 One major problem is the D's inability to create dynamic libraries. D is =
a great language, but without that ability it can only be used for small pr= ograms, tools, etc. and never in production. For one, I question your logic that without dynamic libraries, D can never be more than a hobby language. For two, there is *no problem* with creating D libraries on any platform other than Windows, and it is entirely through Windows' fault that it has the problems it does with DLLs.
 However =93If the library contains a D
 =A0runtime it will be integrated with the current runtime.
 =94 Is this really needed?
What that means is that any static constructors in the library need to be run and the GC in the library's runtime needs to be hooked up to the host's GC (otherwise you'd have two GCs in one app, not fun).
 If the intention is to replace C/C++ some day, why not just provide a dyn=
amic D library? (like in this project: http://www.dsource.org/projects/ddl/= ) It can contain only compiled D code accompanied with meta-data like platf= orm, version, etc. and be used only by D programs. No runtime is needed wit= hin the DDL. When the DDL is loaded it will be managed by the same GC which= manages the program itself. Even Phobos can be a DDL.
 Maybe I am missing something and that's why I would like to hear your opi=
nion. You're missing something :) DDL doesn't require you to have a D runtime in the shared library because unlike DLLs, DDLs can have unresolved externals. That's the main issue: DLLs must have performed all their symbol resolution at link-time, and cannot automatically load symbols out of the host. So, you end up with all the runtime duplicated in the DLL. DDLs, as well as shared libraries on _every other platform_, allow you to have unresolved externals in the shared library which are linked at *load-time*, so that there is one runtime, which is in the host, which all the shared libraries use.
Jul 16 2009
parent reply teo <teo.ubuntu yahoo.com> writes:
Jarrett Billingsley Wrote:

 On Thu, Jul 16, 2009 at 2:12 AM, teo<teo.ubuntu yahoo.com> wrote:
 One major problem is the D's inability to create dynamic libraries. D is a
great language, but without that ability it can only be used for small
programs, tools, etc. and never in production.
For one, I question your logic that without dynamic libraries, D can never be more than a hobby language.
Would you develop an application (excluding tools) as a huge monolithic executable?
  For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.
 
Well, let us assume that you can create dynamic libraries in D and you need to include in each of them Phobos (later maybe just the D Runtime). What is the benefit of that? Can you imagine all your nice dynamic libraries (DLLs, SOs, etc.) written in D and all of them including a huge “payload”? Wouldn't it be better just a simple library only containing the stuff you need?
 If the intention is to replace C/C++ some day, why not just provide a dynamic
D library? (like in this project: http://www.dsource.org/projects/ddl/) It can
contain only compiled D code accompanied with meta-data like platform, version,
etc. and be used only by D programs. No runtime is needed within the DDL. When
the DDL is loaded it will be managed by the same GC which manages the program
itself. Even Phobos can be a DDL.

 Maybe I am missing something and that's why I would like to hear your opinion.
You're missing something :) DDL doesn't require you to have a D runtime in the shared library because unlike DLLs, DDLs can have unresolved externals. That's the main issue: DLLs must have performed all their symbol resolution at link-time, and cannot automatically load symbols out of the host. So, you end up with all the runtime duplicated in the DLL. DDLs, as well as shared libraries on _every other platform_, allow you to have unresolved externals in the shared library which are linked at *load-time*, so that there is one runtime, which is in the host, which all the shared libraries use.
Perhaps I am missing something else ;) because that is exactly my point. DDLs need neither runtime nor Phobos statically linked. Have a look at Java for instance - Java developers create packages (not DLLs) and that is enough. They deploy just the relevant code - no extra bytes. And yes, I know that the JVM is behind the scene. Exactly this is the idea here: the D Runtime can act like the JVM.
Jul 16 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to teo,

 Jarrett Billingsley Wrote:
 
 On Thu, Jul 16, 2009 at 2:12 AM, teo<teo.ubuntu yahoo.com> wrote:
 
 One major problem is the D's inability to create dynamic libraries.
 D is a great language, but without that ability it can only be used
 for small programs, tools, etc. and never in production.
 
For one, I question your logic that without dynamic libraries, D can never be more than a hobby language.
Would you develop an application (excluding tools) as a huge monolithic executable?
Unless I has some some compelling reasons not to, yes, I would prefer to. Aside from reasons like needing to be able to modularly update the app or huge (like GBs) amounts of executable code or some kind of plug-ins via DLLs approach, (all of those are exceptions, not the rule) I don't see any compelling reason to not statically link all of /my/ code together. It has the distinct advantage that things just work without worrying about finding DLLs and checking there versions. (OTOH shipping DLLs to be used by other people is a different story.)
 For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.
Well, let us assume that you can create dynamic libraries in D and you need to include in each of them Phobos (later maybe just the D Runtime). What is the benefit of that? Can you imagine all your nice dynamic libraries (DLLs, SOs, etc.) written in D and all of them including a huge “payload”? Wouldn't it be better just a simple library only containing the stuff you need?
If I'm understanding the situation correctly, what you just described is ONLY a problem on Windows and only because of a design flaw in the way DLL's work. Nobody wants it to work that way and it wouldn't if there were another way to do it.
 If the intention is to replace C/C++ some day, why not just provide
 a dynamic D library? (like in this project:
 http://www.dsource.org/projects/ddl/) It can contain only compiled D
 code accompanied with meta-data like platform, version, etc. and be
 used only by D programs. No runtime is needed within the DDL. When
 the DDL is loaded it will be managed by the same GC which manages
 the program itself. Even Phobos can be a DDL.
 
 Maybe I am missing something and that's why I would like to hear
 your opinion.
 
You're missing something :) DDL doesn't require you to have a D runtime in the shared library because unlike DLLs, DDLs can have unresolved externals. That's the main issue: DLLs must have performed all their symbol resolution at link-time, and cannot automatically load symbols out of the host. So, you end up with all the runtime duplicated in the DLL. DDLs, as well as shared libraries on _every other platform_, allow you to have unresolved externals in the shared library which are linked at *load-time*, so that there is one runtime, which is in the host, which all the shared libraries use.
Perhaps I am missing something else ;) because that is exactly my point. DDLs need neither runtime nor Phobos statically linked. Have a look at Java for instance - Java developers create packages (not DLLs) and that is enough. They deploy just the relevant code - no extra bytes. And yes, I know that the JVM is behind the scene. Exactly this is the idea here: the D Runtime can act like the JVM.
This isn't my expertise but I think you aren't proposing anything new. What you are proposing is the way things work /right now/ on Linux and the way people wish they would work on Windows.
Jul 16 2009
next sibling parent reply Jussi Jumppanen <jussij zeusedit.com> writes:
BCS Wrote:

 If I'm understanding the situation correctly, what you just 
 described is ONLY a problem on Windows and only because
 of a design flaw in the way DLL's work. 
That might be well be the case. But to basically then say that “when developing with D on Windows it is highly recommended that DLL's are not used” will just end up sounding like limitation of D and not of Windows DLLs. fact almost any language you care to name, have no trouble working with DLLs so the question they will be asking is why should D?
Jul 16 2009
parent reply grauzone <none example.net> writes:
Jussi Jumppanen wrote:
 BCS Wrote:
 
 If I'm understanding the situation correctly, what you just 
 described is ONLY a problem on Windows and only because
 of a design flaw in the way DLL's work. 
That might be well be the case. But to basically then say that “when developing with D on Windows it is highly recommended that DLL's are not used” will just end up sounding like limitation of D and not of Windows DLLs.
I know a simple counter measure: use DLLs as a container for the DDL By the way, can't you simply put the runtime into a DLL, and load that by the host program? D DLL would also depend from the runtime DLL. Then the runtime would be shared, wouldn't it?
Jul 16 2009
parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jul 16, 2009 at 9:30 PM, grauzone<none example.net> wrote:
 I know a simple counter measure: use DLLs as a container for the DDL

Hmm!
 By the way, can't you simply put the runtime into a DLL, and load that by
 the host program? D DLL would also depend from the runtime DLL. Then the
 runtime would be shared, wouldn't it?
Even if you did that, you still have the problem where all user-level typeinfo (including typeinfo for every type in the standard library) would be duplicated in the host and the library, which wouldn't solve several issues involved in casting, exception handling, and other things like array sorting. Not to mention you still would have to deal with giving the shared library function pointers etc. About the only *possible* means of *maybe* doing it is by putting most of your host in a DLL itself, and just having a stub program which loads it and calls it. That way DLLs *can* depend on the host, but it requires some ridiculous compiling acrobatics which simply aren't necessary on any other OS. It's such a silly limitation that DDL is not the only library that has been implemented to work around it. EDLL beat us to it: http://edll.sourceforge.net/
Jul 16 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Jarrett Billingsley wrote:
 On Thu, Jul 16, 2009 at 9:30 PM, grauzone<none example.net> wrote:
 I know a simple counter measure: use DLLs as a container for the DDL

Hmm!
You know, this is so obvious in retrospect. ?cookie grauzone What we really need is a new linker that can produce "DDL-ified" DLLs and executables. <thinking type="out-loud" opinion="mostly-uninformed"> <![CDATA[ Let's assume someone was crazy enough to write a new linker. One option for output could be -dll. This would compile the given source files into a static library, and then embed it into a DLL. We can arrange it so that D's shared library loading code recognises DLLs with an embedded DDL library (perhaps a standardised export function: ddl_getEmbeds or something). Even better: if you do this with the new linker:
 link mymain.d dmdrt.dll phobos.dll libfoo.dll
It replaces the regular main with a stub main that starts DDL, loads the requested DLLs via system calls, pulls the embeds out, links everything together and THEN calls the D runtime's main (which then calls YOUR main). You could keep the majority of DDL in dmdrt.dll; the executable itself would only require enough to call LoadLibrary, pull out the embeds and get a pointer to a bootstrap function. This way, code doesn't need to be written to use DDL; the linker takes care of managing the difference. The standard library's shared library loading code could then be extended to be able to load D calls directly (ie: shlib.load!(TypeOfFunction)("package.module.name") or somesuch). The problem, then, is with extern(C), extern(Windows) and extern(C++) functions. *thinks* We could have the linker expose those directly; they have distinct name mangles from D functions, so it should be able to identify them. It could place these functions in the "standard" part of the DLL so that they're accessible from C/C++ code. In order for that to work, though, we'd need to init. the standard library, GC, etc. We can do that in DllMain IF we require that all D DLLs *dynamically* link to the standard library. Because we're using system calls to load the DLLs (along with their embed payload, which is what we're actually interested in), it should only load one copy. If we have, for example, a C app that is using D code as plugins, each plugin will ask the system for "dmdrt.dll" using its minimal embedded DDL stub. But since they're system calls, we should only get one copy. I'm not sure exactly how the system will share that library, though; whether it's per-process or system-wide. In any case, the DDL stub should be able to pull in the full DDL from dmdrt.dll and then use that to link everything together. The nice bonus of this is that DDL just becomes an implementation detail AND we can say "yes, we can do DLLs in D!" even if we're only using them to contain a DDL payload. The one downside I can think of is that if you DID want to distribute a D plugin for a C/C++ program, you'd also need to ship dmdrt.dll alongside it. Although, in that case, it probably wouldn't hurt anything (aside from memory usage) to simply statically link the runtime and standard library in; if the host app is C/C++, then the plugins probably won't be able to stomp all over each other. ]]> </thinking>
Jul 17 2009
next sibling parent BCS <none anon.com> writes:
Hello Daniel,


 Although, in that case, it probably wouldn't hurt
 anything (aside from memory usage)
if that's a problem, you have bigger problems. :)
 to simply statically link the
 runtime and standard library in; if the host app is C/C++, then the
 plugins probably won't be able to stomp all over each other.
Much of the time you should be safe. But if the plugins are allowed to interact (pass data around) and you have two written in D you would need to take care.
Jul 17 2009
prev sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Daniel Keep wrote:
 If we have, for example, a C app that is using D code as plugins, each
 plugin will ask the system for "dmdrt.dll" using its minimal embedded
 DDL stub.  But since they're system calls, we should only get one copy.
  I'm not sure exactly how the system will share that library, though;
 whether it's per-process or system-wide.
 
 In any case, the DDL stub should be able to pull in the full DDL from
 dmdrt.dll and then use that to link everything together.
 
 The nice bonus of this is that DDL just becomes an implementation detail
 AND we can say "yes, we can do DLLs in D!" even if we're only using them
 to contain a DDL payload.
 
 The one downside I can think of is that if you DID want to distribute a
 D plugin for a C/C++ program, you'd also need to ship dmdrt.dll
 alongside it.  Although, in that case, it probably wouldn't hurt
 anything (aside from memory usage) to simply statically link the runtime
 and standard library in; if the host app is C/C++, then the plugins
 probably won't be able to stomp all over each other.
My primary use of D right now is to build DLLs for C++ applications, so I'd be very annoyed if the standard Windows DLL functionality became more convoluted. For custom loading into D applications, why even bother using a DLL as a container? Why not design a file format (maybe even DDL as it currently exists) and use that as the primary dynamic loading & linking machanism, on all platforms? --benji
Jul 17 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"Benji Smith" <dlanguage benjismith.net> wrote in message 
news:h3qus2$1anq$1 digitalmars.com...
 For custom loading into D applications, why even bother using a DLL as a 
 container? Why not design a file format (maybe even DDL as it currently 
 exists) and use that as the primary dynamic loading & linking machanism, 
 on all platforms?
That would make it a lot harder for people to write plugins for the program in anything other than D. Although, it's debatable how important that would be...
Jul 17 2009
parent Robert Fraser <fraserofthenight gmail.com> writes:
Nick Sabalausky wrote:
 "Benji Smith" <dlanguage benjismith.net> wrote in message 
 news:h3qus2$1anq$1 digitalmars.com...
 For custom loading into D applications, why even bother using a DLL as a 
 container? Why not design a file format (maybe even DDL as it currently 
 exists) and use that as the primary dynamic loading & linking machanism, 
 on all platforms?
That would make it a lot harder for people to write plugins for the program in anything other than D. Although, it's debatable how important that would be...
If the application writer wanted to support both, the application writer could most easily do that.
Jul 18 2009
prev sibling parent reply teo <teo.ubuntu yahoo.com> writes:
BCS Wrote:

 Reply to teo,
 
 Jarrett Billingsley Wrote:
 
 On Thu, Jul 16, 2009 at 2:12 AM, teo<teo.ubuntu yahoo.com> wrote:
 
 One major problem is the D's inability to create dynamic libraries.
 D is a great language, but without that ability it can only be used
 for small programs, tools, etc. and never in production.
 
For one, I question your logic that without dynamic libraries, D can never be more than a hobby language.
Would you develop an application (excluding tools) as a huge monolithic executable?
Unless I has some some compelling reasons not to, yes, I would prefer to. Aside from reasons like needing to be able to modularly update the app or huge (like GBs) amounts of executable code or some kind of plug-ins via DLLs approach, (all of those are exceptions, not the rule) I don't see any compelling reason to not statically link all of /my/ code together. It has the distinct advantage that things just work without worrying about finding DLLs and checking there versions. (OTOH shipping DLLs to be used by other people is a different story.)
Well, to some extent this will do the job, but at some point you would need to extract some stuff and put it in libraries, so that it can be reused by other applications. Think about an application which consists of several executables which work together and should share common stuff. Wouldn't you extract it into a library?
Jul 17 2009
parent reply BCS <ao pathlink.com> writes:
Reply to teo,

 BCS Wrote:
 
 Unless I has some some compelling reasons not to, yes, I would prefer
 to. Aside from reasons like needing to be able to modularly update
 the app or huge (like GBs) amounts of executable code or some kind of
 plug-ins via DLLs approach, (all of those are exceptions, not the
 rule) I don't see any compelling reason to not statically link all of
 /my/ code together. It has the distinct advantage that things just
 work without worrying about finding DLLs and checking there versions.
 (OTOH shipping DLLs to be used by other people is a different story.)
 
Well, to some extent this will do the job, but at some point you would need to extract some stuff and put it in libraries, so that it can be reused by other applications. Think about an application which consists of several executables which work together and should share common stuff. Wouldn't you extract it into a library?
Yes, as a static .lib type library that is statically linked in as part of the .exe. If the size of the code duplication becomes an issue, I'll be to busy worrying about other things (like not being able to fit my code and data in a 32bit address space).
Jul 17 2009
parent reply "Nick Sabalausky" <a a.a> writes:
"BCS" <ao pathlink.com> wrote in message 
news:78ccfa2d4382d8cbd4ffb8875fdf news.digitalmars.com...
 Reply to teo,

 Well, to some extent this will do the job, but at some point you would
 need to extract some stuff and put it in libraries, so that it can be
 reused by other applications. Think about an application which
 consists of several executables which work together and should share
 common stuff. Wouldn't you extract it into a library?
Yes, as a static .lib type library that is statically linked in as part of the .exe.
Exactly, and it doesn't even have to be a compiled .lib, it could just be a source-library. I do that all the time. I really don't see any reason to think that modularity and code-reuse would require linking to be dynamic. At least certainly not in the general case.
 If the size of the code duplication becomes an issue, I'll be to busy 
 worrying about other things (like not being able to fit my code and data 
 in a 32bit address space).
Jul 17 2009
parent reply Benji Smith <dlanguage benjismith.net> writes:
Nick Sabalausky wrote:
 "BCS" <ao pathlink.com> wrote in message 
 news:78ccfa2d4382d8cbd4ffb8875fdf news.digitalmars.com...
 Reply to teo,

 Well, to some extent this will do the job, but at some point you would
 need to extract some stuff and put it in libraries, so that it can be
 reused by other applications. Think about an application which
 consists of several executables which work together and should share
 common stuff. Wouldn't you extract it into a library?
Yes, as a static .lib type library that is statically linked in as part of the .exe.
Exactly, and it doesn't even have to be a compiled .lib, it could just be a source-library. I do that all the time. I really don't see any reason to think that modularity and code-reuse would require linking to be dynamic. At least certainly not in the general case.
I agree that source-level modularity, and static linking are preferable most of the time (especially given D's dependency on templates, which don't work so well in compiled libraries). But there are plenty of legitimate situations that mandate dynamic linking, and I think the standard library needs a better solution than what it currently has. --benji
Jul 19 2009
parent "Nick Sabalausky" <a a.a> writes:
"Benji Smith" <dlanguage benjismith.net> wrote in message 
news:h3vmi3$ro9$1 digitalmars.com...
 Nick Sabalausky wrote:
 "BCS" <ao pathlink.com> wrote in message 
 news:78ccfa2d4382d8cbd4ffb8875fdf news.digitalmars.com...
 Reply to teo,

 Well, to some extent this will do the job, but at some point you would
 need to extract some stuff and put it in libraries, so that it can be
 reused by other applications. Think about an application which
 consists of several executables which work together and should share
 common stuff. Wouldn't you extract it into a library?
Yes, as a static .lib type library that is statically linked in as part of the .exe.
Exactly, and it doesn't even have to be a compiled .lib, it could just be a source-library. I do that all the time. I really don't see any reason to think that modularity and code-reuse would require linking to be dynamic. At least certainly not in the general case.
I agree that source-level modularity, and static linking are preferable most of the time (especially given D's dependency on templates, which don't work so well in compiled libraries). But there are plenty of legitimate situations that mandate dynamic linking, and I think the standard library needs a better solution than what it currently has.
Sure, there are plenty of good uses for dynamic linking, thinks that may even require it, and D may have room for improvement in that area (and personally, I'm not saying anything about any particular type of linking being most preferable). It's just that for someone to suggest that dynamic linking is required for non-trivial apps in general or for modular code reuse in general is a bit absurd.
Jul 19 2009
prev sibling next sibling parent reply Trass3r <mrmocool gmx.de> writes:
teo schrieb:
 You're missing something :)  DDL doesn't require you to have a D
 runtime in the shared library because unlike DLLs, DDLs can have
 unresolved externals.  That's the main issue: DLLs must have performed
 all their symbol resolution at link-time, and cannot automatically
 load symbols out of the host.  So, you end up with all the runtime
 duplicated in the DLL.  DDLs, as well as shared libraries on _every
 other platform_, allow you to have unresolved externals in the shared
 library which are linked at *load-time*, so that there is one runtime,
 which is in the host, which all the shared libraries use.
Perhaps I am missing something else ;) because that is exactly my point. DDLs need neither runtime nor Phobos statically linked. Have a look at Java for instance - Java developers create packages (not DLLs) and that is enough. They deploy just the relevant code - no extra bytes. And yes, I know that the JVM is behind the scene. Exactly this is the idea here: the D Runtime can act like the JVM.
So where's your problem? Go use DDL, you may also try h3r3tic's enhanced fork with a new linker: http://team0xf.com:1024/ext/file/70b9addb42d5/ddl/ http://team0xf.com:1024/linker/
Jul 16 2009
parent Trass3r <mrmocool gmx.de> writes:
Trass3r schrieb:
 Go use DDL, you may also try h3r3tic's enhanced fork with a new linker:
 http://team0xf.com:1024/ext/file/70b9addb42d5/ddl/
 http://team0xf.com:1024/linker/
Here's a more detailed explanation: http://h3.team0xf.com/devlog/?p=12
Jul 16 2009
prev sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jul 16, 2009 at 4:44 PM, teo<teo.ubuntu yahoo.com> wrote:

 =A0For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.
Well, let us assume that you can create dynamic libraries in D and you ne=
ed to include in each of them Phobos (later maybe just the D Runtime). What= is the benefit of that? Can you imagine all your nice dynamic libraries (D= LLs, SOs, etc.) written in D and all of them including a huge =93payload=94= ? Wouldn't it be better just a simple library only containing the stuff you= need? I don't think you're getting it. ON WINDOWS, DLLs are not allowed to have unresolved externals. So if you create a DLL in D, yes, Phobos will be linked in. THERE IS NOTHING THAT CAN BE DONE ABOUT THAT. It's a limitation on the way DLLs work. ON EVERY OTHER OPERATING SYSTEM (Linux, Unix, OSX, *whatever*), shared libraries CAN have unresolved externals, so Phobos *does not* have to be included in the shared libraries. Shared libraries ALREADY work the way you expect them to on every OS besides Windows. The ONLY way to solve the problem with DLLs on Windows is to not use DLLs. Java solves it by not using any platform-dependent libraries, instead using its own .class files. This is *exactly* what DDL does. So, I'm not sure what you see as the problem here. DDL works fine on Windows. Use it.
Jul 16 2009
next sibling parent reply Rainer Deyke <rainerd eldwood.com> writes:
Jarrett Billingsley wrote:
 ON WINDOWS, DLLs are not allowed to have unresolved externals.  So if
 you create a DLL in D, yes, Phobos will be linked in.  THERE IS
 NOTHING THAT CAN BE DONE ABOUT THAT.  It's a limitation on the way
 DLLs work.
In theory, wouldn't it also be possible to solve this problem by passing a pointer to the external dependencies into the DLL via an initialization function? -- Rainer Deyke - rainerd eldwood.com
Jul 16 2009
next sibling parent BCS <ao pathlink.com> writes:
Reply to Rainer,

 Jarrett Billingsley wrote:
 
 ON WINDOWS, DLLs are not allowed to have unresolved externals.  So if
 you create a DLL in D, yes, Phobos will be linked in.  THERE IS
 NOTHING THAT CAN BE DONE ABOUT THAT.  It's a limitation on the way
 DLLs work.
 
In theory, wouldn't it also be possible to solve this problem by passing a pointer to the external dependencies into the DLL via an initialization function?
With a function resolver to pass in from the host, a whole host of function pointers and wrapper functions, I think you could make this work. It would be mess to do by hand, but with a tool to muck through the .OBJs (yuck) and build the functions... Another option (double yuck) would be to trick the linker into running and then build ("self" modifying) code into the DLL that somehow knows (another tool and multiple link passes?) where all the fix ups are and resolves them on load. (problem: your code can't be read only anymore)
Jul 16 2009
prev sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jul 16, 2009 at 7:13 PM, Rainer Deyke<rainerd eldwood.com> wrote:
 Jarrett Billingsley wrote:
 ON WINDOWS, DLLs are not allowed to have unresolved externals. =A0So if
 you create a DLL in D, yes, Phobos will be linked in. =A0THERE IS
 NOTHING THAT CAN BE DONE ABOUT THAT. =A0It's a limitation on the way
 DLLs work.
In theory, wouldn't it also be possible to solve this problem by passing a pointer to the external dependencies into the DLL via an initialization function?
That's how many apps on Windows do plugins; they pass a sort of global structure pointer that holds a bunch of function pointers into the host. Basically doing the runtime linking by hand. It's *possible*, but very tedious. It seems almost pointless when you consider the existence of DDL.
Jul 16 2009
parent BCS <ao pathlink.com> writes:
Reply to Jarrett,


 It's *possible*, but very tedious.  It seems almost pointless when you
 consider the existence of DDL.
Nothing is to tedious in programming. If a task is tedious, it's almost a given that it's automatable.
Jul 16 2009
prev sibling next sibling parent reply Benji Smith <dlanguage benjismith.net> writes:
Jarrett Billingsley wrote:
 On Thu, Jul 16, 2009 at 4:44 PM, teo<teo.ubuntu yahoo.com> wrote:
 
  For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.
Well, let us assume that you can create dynamic libraries in D and you need to include in each of them Phobos (later maybe just the D Runtime). What is the benefit of that? Can you imagine all your nice dynamic libraries (DLLs, SOs, etc.) written in D and all of them including a huge “payload”? Wouldn't it be better just a simple library only containing the stuff you need?
I don't think you're getting it. ON WINDOWS, DLLs are not allowed to have unresolved externals. So if you create a DLL in D, yes, Phobos will be linked in. THERE IS NOTHING THAT CAN BE DONE ABOUT THAT. It's a limitation on the way DLLs work. ON EVERY OTHER OPERATING SYSTEM (Linux, Unix, OSX, *whatever*), shared libraries CAN have unresolved externals, so Phobos *does not* have to be included in the shared libraries. Shared libraries ALREADY work the way you expect them to on every OS besides Windows. The ONLY way to solve the problem with DLLs on Windows is to not use DLLs. Java solves it by not using any platform-dependent libraries, instead using its own .class files. This is *exactly* what DDL does. So, I'm not sure what you see as the problem here. DDL works fine on Windows. Use it.
You learn something new everyday. That's pretty cool. Incidentally, this is exactly the kind of stuff that I'd love to see built right into DRuntime or Phobos. I don't have a use for it right now (cuz my project is simple enough not to need dynamic loading), but in the future, I'd be reluctant to use DDL because: 1) Dynamic loading is something that, to me, seems completely fundamental to the runtime system, and I'd be hesitant to trust a third-party library to keep up-to-date with the current compiler & standard library. 2) DDL isn't even really a third-party library. It's more like a fourth-party, since (I assume) it really requires the h3r3tic patch to work correctly. Building this kind of functionality into the standard library would make those issues irrelevant. These kinds of issues are the ones that excite me the most and are the things I'd like to see D pay the most attention to. From my perspective, features of the runtime and standard library are often much more compelling than new language features. --benji
Jul 16 2009
parent teo <teo.ubuntu yahoo.com> writes:
Benji Smith Wrote:

 Jarrett Billingsley wrote:
 On Thu, Jul 16, 2009 at 4:44 PM, teo<teo.ubuntu yahoo.com> wrote:
 
  For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.
Well, let us assume that you can create dynamic libraries in D and you need to include in each of them Phobos (later maybe just the D Runtime). What is the benefit of that? Can you imagine all your nice dynamic libraries (DLLs, SOs, etc.) written in D and all of them including a huge “payload”? Wouldn't it be better just a simple library only containing the stuff you need?
I don't think you're getting it. ON WINDOWS, DLLs are not allowed to have unresolved externals. So if you create a DLL in D, yes, Phobos will be linked in. THERE IS NOTHING THAT CAN BE DONE ABOUT THAT. It's a limitation on the way DLLs work. ON EVERY OTHER OPERATING SYSTEM (Linux, Unix, OSX, *whatever*), shared libraries CAN have unresolved externals, so Phobos *does not* have to be included in the shared libraries. Shared libraries ALREADY work the way you expect them to on every OS besides Windows. The ONLY way to solve the problem with DLLs on Windows is to not use DLLs. Java solves it by not using any platform-dependent libraries, instead using its own .class files. This is *exactly* what DDL does. So, I'm not sure what you see as the problem here. DDL works fine on Windows. Use it.
You learn something new everyday. That's pretty cool. Incidentally, this is exactly the kind of stuff that I'd love to see built right into DRuntime or Phobos. I don't have a use for it right now (cuz my project is simple enough not to need dynamic loading), but in the future, I'd be reluctant to use DDL because: 1) Dynamic loading is something that, to me, seems completely fundamental to the runtime system, and I'd be hesitant to trust a third-party library to keep up-to-date with the current compiler & standard library.
Agree.
 2) DDL isn't even really a third-party library. It's more like a 
 fourth-party, since (I assume) it really requires the h3r3tic patch to 
 work correctly.
 
 Building this kind of functionality into the standard library would make 
 those issues irrelevant.
 
 These kinds of issues are the ones that excite me the most and are the 
 things I'd like to see D pay the most attention to. From my perspective, 
 features of the runtime and standard library are often much more 
 compelling than new language features.
 
I second that. (I like your wording.) It is nice to have some fancy operators and constructions, but usability is what the people are looking for and it comes mostly with the libraries. In our case these are the D Runtime and Phobos. I really would like to see a kind of DDL support in the Runtime. There is no need supporting creation of DLLs with D.
Jul 16 2009
prev sibling parent reply teo <teo.ubuntu yahoo.com> writes:
Jarrett Billingsley Wrote:

 ON EVERY OTHER OPERATING SYSTEM (Linux, Unix, OSX, *whatever*), shared
 libraries CAN have unresolved externals, so Phobos *does not* have to
 be included in the shared libraries.  Shared libraries ALREADY work
 the way you expect them to on every OS besides Windows.
 
Hmm, you say it is working. Can you show me how to do that on 32-bit Linux with dmd? How would you compile Phobos as an external library? Please let me know, if you are aware of an article describing that. Thank you in advance.
Jul 16 2009
parent reply Jesse Phillips <jessekphillips gmail.com> writes:
On Fri, 17 Jul 2009 01:35:37 -0400, teo wrote:

 Hmm, you say it is working. Can you show me how to do that on 32-bit
 Linux with dmd? How would you compile Phobos as an external library?
 Please let me know, if you are aware of an article describing that.
 Thank you in advance.
My guess is that you should be able to follow a shared library tutorial http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html Then just modify the GCC commands for DMD gcc -Wall -fPIC -c *.c Becomes: dmd -fPIC -c *.d Probably can leave alone: gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o gcc -Wall -L/opt/lib prog.c -lctest -o prog Becomes: dmd -L-L/opt/lib prog.d -L-lctest I have not tested this, but nor have I got it to work in C, but I only blame myself.
Jul 16 2009
parent reply teo <teo.ubuntu yahoo.com> writes:
On Fri, 17 Jul 2009 06:15:18 +0000, Jesse Phillips wrote:

 On Fri, 17 Jul 2009 01:35:37 -0400, teo wrote:
 
 Hmm, you say it is working. Can you show me how to do that on 32-bit
 Linux with dmd? How would you compile Phobos as an external library?
 Please let me know, if you are aware of an article describing that.
 Thank you in advance.
My guess is that you should be able to follow a shared library tutorial http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html Then just modify the GCC commands for DMD gcc -Wall -fPIC -c *.c Becomes: dmd -fPIC -c *.d Probably can leave alone: gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o gcc -Wall -L/opt/lib prog.c -lctest -o prog Becomes: dmd -L-L/opt/lib prog.d -L-lctest I have not tested this, but nor have I got it to work in C, but I only blame myself.
I did some tests and here are the results: D cannot be used in Shared Objects. The only case that works is when no classes are exported and when there are no references to Phobos within the library. This is my setup: $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/lib ========== ========== Only this case WORKS! module test; // file "test.d" extern(C) { int test1() { return 1; } string test2() { return "Hello World!"; } } $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o $ sudo mv libtest.so /opt/lib/ --- module main; // file "prog.d" import std.stdio; extern(C) int test1(); extern(C) string test2(); void main() { writefln("Result: %d", test1()); writefln("Result: %s", test2()); return; } $ dmd prog.d -L-L/opt/lib -L-ltest ========== DOESN'T WORK without extern(C). Cannot compile the program. module test; // file "test.d" int test() { return 1; } $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o $ sudo mv libtest.so /opt/lib/ --- module main; // file "prog.d" import std.stdio; extern(C) int test(); void main() { writefln("Result: %d", test()); return; } $ dmd prog.d -L-L/opt/lib -L-ltest prog.o: In function `_Dmain': prog.d:(.text._Dmain+0x10): undefined reference to `test' collect2: ld returned 1 exit status --- errorlevel 1 ========== DOESN'T WORK with classes defined in the library. The program cannot be compiled. module test; // file "test.d" extern(C) { class Test { private int n; public this(int i) { n = i; } } Test getTest() { return new Test(1); } } $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o $ sudo mv libtest.so /opt/lib/ --- module main; // file "prog.d" extern(C) Test getTest(); void main() { Test t = getTest(); return; } $ dmd prog.d -L-L/opt/lib -L-ltest prog.d(3): Error: identifier 'Test' is not defined prog.d(3): Error: Test is used as a type ========== DOESN'T WORK when Phobos is referenced within the library. module test; // file "test.d" import std.stdio; extern(C) { void test() { writefln("Hello World!"); return; } } $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o /usr/bin/ld: libtest.so: No symbol version section for versioned symbol `_d_throw 4' /usr/bin/ld: final link failed: Nonrepresentable section on output collect2: ld returned 1 exit status ==========
Jul 26 2009
next sibling parent reply BCS <ao pathlink.com> writes:
Reply to teo,

 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
 
two of your fail cases have non SO realted errors:
 ==========
 DOESN'T WORK without extern(C). Cannot compile the program.
 module test; // file "test.d"
 int test()
 {
 return 1;
 }
 ---
 module main; // file "prog.d"
 import std.stdio;
 extern(C) int test();
this should not be extern(C).
 void main()
 {
 writefln("Result: %d", test());
 return;
 }
 ==========
 DOESN'T WORK with classes defined in the library. The program cannot
 be compiled.
 module test; // file "test.d"
 extern(C)
 {
 class Test
 {
[...]
 }
 }
An extern(C) class would be meaningless and I don't think they are even legal. I can't seem tor repro it with the version I have here (1.034) but I got an error from this code on another system: extern(C) class C { } C Fn(){return new C();}
Jul 27 2009
parent reply teo <teo.ubuntu.remove yahoo.com> writes:
On Mon, 27 Jul 2009 17:17:35 +0000, BCS wrote:

 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
 
 
two of your fail cases have non SO realted errors:
Correct. These are shortcomings of D.
 ==========
 DOESN'T WORK without extern(C). Cannot compile the program. module
 test; // file "test.d"
 int test()
 {
 return 1;
 }
 ---
 module main; // file "prog.d"
 import std.stdio;
 extern(C) int test();
this should not be extern(C).
How will you do it? Give me an example please.
 void main()
 {
 writefln("Result: %d", test());
 return;
 }
 ==========
 DOESN'T WORK with classes defined in the library. The program cannot be
 compiled.
 module test; // file "test.d"
 extern(C)
 {
 class Test
 {
[...]
 }
 }
An extern(C) class would be meaningless and I don't think they are even legal. I can't seem tor repro it with the version I have here (1.034) but I got an error from this code on another system: extern(C) class C { } C Fn(){return new C();}
I use v2.031 and cannot export a class out of a library.
Jul 27 2009
parent BCS <ao pathlink.com> writes:
Reply to teo,

 On Mon, 27 Jul 2009 17:17:35 +0000, BCS wrote:
 
 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in
 Shared Objects. The only case that works is when no classes are
 exported and when there are no references to Phobos within the
 library.
 
two of your fail cases have non SO realted errors:
Correct. These are shortcomings of D.
 ==========
 DOESN'T WORK without extern(C). Cannot compile the program. module
 test; // file "test.d"
 int test()
 {
 return 1;
 }
 ---
 module main; // file "prog.d"
 import std.stdio;
 extern(C) int test();
this should not be extern(C).
How will you do it? Give me an example please.
Remove "extern(C)" from the prototype in that example an try it again?
 void main()
 {
 writefln("Result: %d", test());
 return;
 }
 ==========
 DOESN'T WORK with classes defined in the library. The program cannot
 be
 compiled.
 module test; // file "test.d"
 extern(C)
 {
 class Test
 {
[...]
 }
 }
An extern(C) class would be meaningless and I don't think they are even legal. I can't seem tor repro it with the version I have here (1.034) but I got an error from this code on another system: extern(C) class C { } C Fn(){return new C();}
I use v2.031 and cannot export a class out of a library.
Have you tried that example case again but with all "exter(C)" removed?
Jul 27 2009
prev sibling parent reply BCS <ao pathlink.com> writes:
Reply to teo,

 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
this works: module test; int test1() { return 0; } char[] test2() { return "hello world"; } class C { int i; this(int j) { i = j; } int get(){ return i; } } ---- module main; import test; void main() { test1(); test2(); int i = (new C(5)).get(); } $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o $ dmd main.d -L-L`pwd` -L-ltest All the problems were resolved by replacing the prototypes with imports.
Jul 27 2009
next sibling parent reply teo <teo.ubuntu.remove yahoo.com> writes:
On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:

 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
this works:
no it does not
 module test;
 int test1() { return 0; }
 char[] test2() { return "hello world"; }
 
 class C
 {
     int i;
     this(int j) { i = j; }
     int get(){ return i; }
 }
 
 ----
 
 module main;
 import test;
 void main()
 {
    test1();
    test2();
    int i = (new C(5)).get();
 }
 
 $ dmd -fPIC -c test.d
 $ gcc -shared -o libtest.so test.o
 $ dmd main.d -L-L`pwd` -L-ltest
 
 All the problems were resolved by replacing the prototypes with imports.
split your files in two directories and compile them separately in lib(rary) directory I have test.d module test; // file "test.d" int test1() { return 1; } class Test { private int n; public this(int i) { n = i; } } $ cd lib/ $ dmd -fPIC -c test.d $ gcc -shared -o libtest.so test.o $ sudo mv libtest.so /opt/lib/ and prog.d in exe(cutable) directory module main; // file "prog.d" import std.stdio; import test; void main() { writefln("Result: %d", test1()); Test t = new Test(1); return; } $ cd ../exe/ $ dmd prog.d -L-L/opt/lib -L-ltest prog.d(2): Error: module test cannot read file 'test.d'
Jul 27 2009
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
teo wrote:
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,

 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
this works:
no it does not
 ...
split your files in two directories and compile them separately
So your justification for it not working is because you deliberately didn't follow his instructions and broke the compile?
 in lib(rary) directory I have test.d
 
 module test; // file "test.d"
 int test1() { return 1; }
 class Test
 {
 	private int n;
 	public this(int i) { n = i; }
 }
 $ cd lib/
 $ dmd -fPIC -c test.d 
 $ gcc -shared -o libtest.so test.o
 $ sudo mv libtest.so /opt/lib/
 
 and prog.d in exe(cutable) directory
 
 module main; // file "prog.d"
 import std.stdio;
 import test;
 void main()
 {
 	writefln("Result: %d", test1());
 	Test t = new Test(1);
 	return;
 }
 $ cd ../exe/
 $ dmd prog.d -L-L/opt/lib -L-ltest
 prog.d(2): Error: module test cannot read file 'test.d'
Well of course it can't compile: YOU MOVED test.d! What do you expect when you tell it to import a file that no longer exists? The compiler is not psychic. If you really, absolutely have to have the two parts in different directories, just generate a header file. dmd -H -c -o- test.d That generates test.di, which you have to make available to prog.d. Of course, in this particular case, test.di is exactly the same as test.d, since all the functions are small enough to be inlined.
Jul 28 2009
next sibling parent BCS <ao pathlink.com> writes:
Reply to Daniel,

 Well of course it can't compile: YOU MOVED test.d!  What do you expect
 when you tell it to import a file that no longer exists?  The compiler
 is not psychic.
 
 If you really, absolutely have to have the two parts in different
 directories, just generate a header file.
 
 dmd -H -c -o- test.d
 
 That generates test.di, which you have to make available to prog.d.
 
 Of course, in this particular case, test.di is exactly the same as
 test.d, since all the functions are small enough to be inlined.
 
ditto. I was going to post exactly that point.
Jul 28 2009
prev sibling next sibling parent teo <teo.ubuntu.remove yahoo.com> writes:
On Tue, 28 Jul 2009 17:02:31 +1000, Daniel Keep wrote:

 teo wrote:
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,

 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
this works:
no it does not
 ...
split your files in two directories and compile them separately
So your justification for it not working is because you deliberately didn't follow his instructions and broke the compile?
now I followed them, but it still doesn't work
Jul 28 2009
prev sibling parent reply =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
Daniel Keep wrote:
=20
 teo wrote:
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:

 Reply to teo,

 I did some tests and here are the results: D cannot be used in Share=
d
 Objects. The only case that works is when no classes are exported an=
d
 when there are no references to Phobos within the library.
this works:
no it does not
 ...
split your files in two directories and compile them separately
=20 So your justification for it not working is because you deliberately didn't follow his instructions and broke the compile? =20
 in lib(rary) directory I have test.d

 module test; // file "test.d"
 int test1() { return 1; }
 class Test
 {
 	private int n;
 	public this(int i) { n =3D i; }
 }
 $ cd lib/
 $ dmd -fPIC -c test.d=20
 $ gcc -shared -o libtest.so test.o
 $ sudo mv libtest.so /opt/lib/

 and prog.d in exe(cutable) directory

 module main; // file "prog.d"
 import std.stdio;
 import test;
 void main()
 {
 	writefln("Result: %d", test1());
 	Test t =3D new Test(1);
 	return;
 }
 $ cd ../exe/
 $ dmd prog.d -L-L/opt/lib -L-ltest
 prog.d(2): Error: module test cannot read file 'test.d'
=20 Well of course it can't compile: YOU MOVED test.d! What do you expect when you tell it to import a file that no longer exists? The compiler is not psychic. =20 If you really, absolutely have to have the two parts in different directories, just generate a header file. =20 dmd -H -c -o- test.d =20 That generates test.di, which you have to make available to prog.d. =20 Of course, in this particular case, test.di is exactly the same as test.d, since all the functions are small enough to be inlined.
Or just use the -I command line argument to point to the folder in=20 which test.d is stored. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jul 28 2009
parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
J=C3=A9r=C3=B4me M. Berger wrote:
     Or just use the -I command line argument to point to the folder in =
 which test.d is stored.
=20
         Jerome
PS: Just as in C/C++, really --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Jul 28 2009
prev sibling parent reply teo <teo.ubuntu.remove yahoo.com> writes:
On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:

 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
this works:
it doesn't work with v2.031
 module test;
 int test1() { return 0; }
dmd complains:
 char[] test2() { return "hello world"; }
 
test.d(3): Error: cannot implicitly convert expression ("hello world") of type immutable(char)[] to char[] when I change it to: string test2() { return "hello world"; } $ dmd main.d -L-L`pwd` -L-ltest main.d(6): Error: undefined identifier test2 main.d(6): Error: function expected before (), not test2 of type int main.d(7): Error: identifier 'C' is not defined main.d(7): Error: C is used as a type main.d(7): Error: new can only create structs, dynamic arrays or class objects, not void's main.d(7): Error: no property 'get' for type 'void' main.d(7): Error: function expected before (), not __error of type int
Jul 28 2009
parent reply BCS <ao pathlink.com> writes:
Reply to teo,

 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in
 Shared Objects. The only case that works is when no classes are
 exported and when there are no references to Phobos within the
 library.
 
this works:
it doesn't work with v2.031
 module test;
 int test1() { return 0; }
dmd complains:
 char[] test2() { return "hello world"; }
 
test.d(3): Error: cannot implicitly convert expression ("hello world") of type immutable(char)[] to char[] when I change it to: string test2() { return "hello world"; } $ dmd main.d -L-L`pwd` -L-ltest main.d(6): Error: undefined identifier test2 main.d(6): Error: function expected before (), not test2 of type int main.d(7): Error: identifier 'C' is not defined main.d(7): Error: C is used as a type main.d(7): Error: new can only create structs, dynamic arrays or class objects, not void's main.d(7): Error: no property 'get' for type 'void' main.d(7): Error: function expected before (), not __error of type int
That's not a SO realted problem. Try building it as a non-SO program, fix any errors you get there and then go back to the SO version. for starters try: public string test2() { return "hello world"; } p.s. Are you trying to make it fail or do you want it to work?
Jul 28 2009
next sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Tue, 28 Jul 2009 21:01:33 +0000 (UTC), BCS wrote:

 Reply to teo,
 
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in
 Shared Objects. The only case that works is when no classes are
 exported and when there are no references to Phobos within the
 library.
 
this works:
it doesn't work with v2.031
 module test;
 int test1() { return 0; }
dmd complains:
 char[] test2() { return "hello world"; }
 
test.d(3): Error: cannot implicitly convert expression ("hello world") of type immutable(char)[] to char[] when I change it to: string test2() { return "hello world"; } $ dmd main.d -L-L`pwd` -L-ltest main.d(6): Error: undefined identifier test2 main.d(6): Error: function expected before (), not test2 of type int main.d(7): Error: identifier 'C' is not defined main.d(7): Error: C is used as a type main.d(7): Error: new can only create structs, dynamic arrays or class objects, not void's main.d(7): Error: no property 'get' for type 'void' main.d(7): Error: function expected before (), not __error of type int
That's not a SO realted problem. Try building it as a non-SO program, fix any errors you get there and then go back to the SO version. for starters try: public string test2() { return "hello world"; }
Maybe "export string test2() {...}" ? teo, such discussions belong in D.learn.
Jul 28 2009
parent teo <teo.ubuntu.remove yahoo.com> writes:
On Wed, 29 Jul 2009 03:51:24 +0400, Sergey Gromov wrote:

 Tue, 28 Jul 2009 21:01:33 +0000 (UTC), BCS wrote:
 
 Reply to teo,
 
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in
 Shared Objects. The only case that works is when no classes are
 exported and when there are no references to Phobos within the
 library.
 
this works:
it doesn't work with v2.031
 module test;
 int test1() { return 0; }
dmd complains:
 char[] test2() { return "hello world"; }
 
test.d(3): Error: cannot implicitly convert expression ("hello world") of type immutable(char)[] to char[] when I change it to: string test2() { return "hello world"; } $ dmd main.d -L-L`pwd` -L-ltest main.d(6): Error: undefined identifier test2 main.d(6): Error: function expected before (), not test2 of type int main.d(7): Error: identifier 'C' is not defined main.d(7): Error: C is used as a type main.d(7): Error: new can only create structs, dynamic arrays or class objects, not void's main.d(7): Error: no property 'get' for type 'void' main.d(7): Error: function expected before (), not __error of type int
That's not a SO realted problem. Try building it as a non-SO program, fix any errors you get there and then go back to the SO version. for starters try: public string test2() { return "hello world"; }
Maybe "export string test2() {...}" ? teo, such discussions belong in D.learn.
Correct. This thread has had another scope. I will move that question to D.learn.
Jul 29 2009
prev sibling parent teo <teo.ubuntu.remove yahoo.com> writes:
On Tue, 28 Jul 2009 21:01:33 +0000, BCS wrote:

 Reply to teo,
 
 On Mon, 27 Jul 2009 20:34:44 +0000, BCS wrote:
 
 Reply to teo,
 
 I did some tests and here are the results: D cannot be used in Shared
 Objects. The only case that works is when no classes are exported and
 when there are no references to Phobos within the library.
 
this works:
it doesn't work with v2.031
 module test;
 int test1() { return 0; }
dmd complains:
 char[] test2() { return "hello world"; }
 
test.d(3): Error: cannot implicitly convert expression ("hello world") of type immutable(char)[] to char[] when I change it to: string test2() { return "hello world"; } $ dmd main.d -L-L`pwd` -L-ltest main.d(6): Error: undefined identifier test2 main.d(6): Error: function expected before (), not test2 of type int main.d(7): Error: identifier 'C' is not defined main.d(7): Error: C is used as a type main.d(7): Error: new can only create structs, dynamic arrays or class objects, not void's main.d(7): Error: no property 'get' for type 'void' main.d(7): Error: function expected before (), not __error of type int
That's not a SO realted problem. Try building it as a non-SO program, fix any errors you get there and then go back to the SO version. for starters try: public string test2() { return "hello world"; } p.s. Are you trying to make it fail or do you want it to work?
I *definitely* need a working solution! And I followed your instructions, but I use dmd v2.031
Jul 29 2009
prev sibling next sibling parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jul 16, 2009 at 10:44 AM, Jarrett
Billingsley<jarrett.billingsley gmail.com> wrote:
 On Thu, Jul 16, 2009 at 2:12 AM, teo<teo.ubuntu yahoo.com> wrote:
 One major problem is the D's inability to create dynamic libraries. D is=
a great language, but without that ability it can only be used for small p= rograms, tools, etc. and never in production.
 For one, I question your logic that without dynamic libraries, D can
 never be more than a hobby language. =A0For two, there is *no problem*
 with creating D libraries on any platform other than Windows, and it
 is entirely through Windows' fault that it has the problems it does
 with DLLs.

 However =93If the library contains a D
 =A0runtime it will be integrated with the current runtime.
 =94 Is this really needed?
What that means is that any static constructors in the library need to be run and the GC in the library's runtime needs to be hooked up to the host's GC (otherwise you'd have two GCs in one app, not fun).
 If the intention is to replace C/C++ some day, why not just provide a dy=
namic D library? (like in this project: http://www.dsource.org/projects/ddl= /) It can contain only compiled D code accompanied with meta-data like plat= form, version, etc. and be used only by D programs. No runtime is needed wi= thin the DDL. When the DDL is loaded it will be managed by the same GC whic= h manages the program itself. Even Phobos can be a DDL.
 Maybe I am missing something and that's why I would like to hear your op=
inion.
 You're missing something :) =A0DDL doesn't require you to have a D
 runtime in the shared library because unlike DLLs, DDLs can have
 unresolved externals. =A0That's the main issue: DLLs must have performed
 all their symbol resolution at link-time, and cannot automatically
 load symbols out of the host. =A0So, you end up with all the runtime
 duplicated in the DLL. =A0DDLs, as well as shared libraries on _every
 other platform_, allow you to have unresolved externals in the shared
 library which are linked at *load-time*, so that there is one runtime,
 which is in the host, which all the shared libraries use.
Furthermore, even if you *could* somehow work out a solution whereby regular DLLs could be made and transparently loaded, there's an even more major problem: the way exception handling is implemented on Windows means that exceptions cannot be thrown out of DLLs into the host. It's just not something that can be solved, from what I understand.
Jul 16 2009
prev sibling parent reply novice2 <sorry noem.ail> writes:
sorry, i don't understand: how D differ from C or C++ in all related to DLL in
Windows? imho, only difference from MS VC is: VC have runtime in DLL form, but
D have no.
Jul 16 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Fri, Jul 17, 2009 at 12:43 AM, novice2<sorry noem.ail> wrote:
 sorry, i don't understand: how D differ from C or C++ in all related to DLL in
Windows? imho, only difference from MS VC is: VC have runtime in DLL form, but
D have no.
C++ does not have mounds of runtime type information. D does. D uses it for all sorts of things. And it's not *just* the runtime that has the type info, it's every piece of D code you compile. If the type info is duplicated, weird things happen.
Jul 16 2009