Re: Can I create static c callable library?

2018-09-28 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Sep 28, 2018 at 02:08:25PM +, Atila Neves via Digitalmars-d-learn 
wrote:
> On Thursday, 27 September 2018 at 23:53:50 UTC, Steven Schveighoffer wrote:
[...]
> > Since C initialization functions have no order to them, it's
> > possible that some  initialization functions in the D runtime are
> > using uninitialized pieces of the C runtime
> 
> No, that can't happen. The C runtime is initialised no matter what you
> do (unless you write `_start` yourself), _then_ the global
> constructors are run. The code I wrote isn't standard C - it's just
> that gcc/clang/cl are all also C++ compilers so they chose to extend
> the already existing functionality to C.
[...]

Potentially some C libraries have not yet been initialized, though.  I
don't know if the druntime init depends on any of them -- it's doubtful,
but if it does, it may cause problems depending on which order library
ctors are called.


T

-- 
In a world without fences, who needs Windows and Gates? -- Christian Surchi


Re: Can I create static c callable library?

2018-09-28 Thread Atila Neves via Digitalmars-d-learn
On Thursday, 27 September 2018 at 23:53:50 UTC, Steven 
Schveighoffer wrote:

On 9/27/18 8:16 AM, Atila Neves wrote:
On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg 
wrote:
On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M 
Davis wrote:


If you use -betterC, then it's trivial, because your D 
program is restricted to extern(C) functions and features 
which don't require druntime. It can also be done without 
-betterC (and thus with druntime), but it gets to be _way_ 
more of a pain, because it requires that you manually 
initialize druntime - either by forcing whatever is using 
your "C" library to call a specific function to initialize 
druntime before using any of its normal functions or by 
having every function in the library check whether druntime 
has been initialized yet and initialize it if it hasn't been 
before it does whatever it's supposed to do.


Shouldn't it be possible to use a C initialization function, 
i.e. pragma(crt_constructor) to initialize druntime? Then it 
only needs to be initialized once and it's not required to 
check if it's initialized all the time.


--
/Jacob Carlborg


Even easier, compile this C file and add the resulting object 
file to your (now mostly) D static library:


---
extern int rt_init(void);
extern int rt_term(void);

__attribute__((__constructor__)) void dinit(void) {
     rt_init();
}
__attribute__((__destructor__)) void dterm(void) {
     rt_term();
}
---

The C runtime will initialise the D runtime for you.



I will point out that this is EXACTLY what 
pragma(crt_constructor) does.


Really? Huh. You live, you learn. I didn't even know that pragma 
existed - it's not listed here at all:


https://dlang.org/spec/pragma.html



And my comments still aren't answered -- I'm not sure whether 
this works correctly or not, as we don't test initializing 
druntime before C main runs.


It's worked for me in practice.

Since C initialization functions have no order to them, it's 
possible that some  initialization functions in the D runtime 
are using uninitialized pieces of the C runtime


No, that can't happen. The C runtime is initialised no matter 
what you do (unless you write `_start` yourself), _then_ the 
global constructors are run. The code I wrote isn't standard C - 
it's just that gcc/clang/cl are all also C++ compilers so they 
chose to extend the already existing functionality to C.






Re: Can I create static c callable library?

2018-09-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/27/18 8:16 AM, Atila Neves wrote:

On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg wrote:

On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis wrote:

If you use -betterC, then it's trivial, because your D program is 
restricted to extern(C) functions and features which don't require 
druntime. It can also be done without -betterC (and thus with 
druntime), but it gets to be _way_ more of a pain, because it 
requires that you manually initialize druntime - either by forcing 
whatever is using your "C" library to call a specific function to 
initialize druntime before using any of its normal functions or by 
having every function in the library check whether druntime has been 
initialized yet and initialize it if it hasn't been before it does 
whatever it's supposed to do.


Shouldn't it be possible to use a C initialization function, i.e. 
pragma(crt_constructor) to initialize druntime? Then it only needs to 
be initialized once and it's not required to check if it's initialized 
all the time.


--
/Jacob Carlborg


Even easier, compile this C file and add the resulting object file to 
your (now mostly) D static library:


---
extern int rt_init(void);
extern int rt_term(void);

__attribute__((__constructor__)) void dinit(void) {
     rt_init();
}
__attribute__((__destructor__)) void dterm(void) {
     rt_term();
}
---

The C runtime will initialise the D runtime for you.



I will point out that this is EXACTLY what pragma(crt_constructor) does.

And my comments still aren't answered -- I'm not sure whether this works 
correctly or not, as we don't test initializing druntime before C main runs.


-Steve


Re: Can I create static c callable library?

2018-09-27 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Sep 27, 2018 at 09:48:50PM +, Adam D. Ruppe via Digitalmars-d-learn 
wrote:
> On Thursday, 27 September 2018 at 21:41:31 UTC, H. S. Teoh wrote:
> > Though I'm not sure what will happen if your C program tries loading
> > two or more D libraries that use this trick... is rt_init()
> > idempotent?
> 
> It just refcounts itself.

Does that mean we could potentially make this "trick" the standard
druntime initialization?  Then we could make things work by default
whether you compile a standalone executable or a shared library.

Though I'm not sure what happens if multiple libraries each ship with
their own copy of druntime...


T

-- 
Bomb technician: If I'm running, try to keep up.


Re: Can I create static c callable library?

2018-09-27 Thread Adam D. Ruppe via Digitalmars-d-learn

On Thursday, 27 September 2018 at 21:41:31 UTC, H. S. Teoh wrote:
Though I'm not sure what will happen if your C program tries 
loading two or more D libraries that use this trick... is 
rt_init() idempotent?


It just refcounts itself.


Re: Can I create static c callable library?

2018-09-27 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Sep 27, 2018 at 03:11:26PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> On Thursday, September 27, 2018 6:16:13 AM MDT Atila Neves via Digitalmars-
> d-learn wrote:
[...]
> > Even easier, compile this C file and add the resulting object
> > file to your (now mostly) D static library:
> >
> > ---
> > extern int rt_init(void);
> > extern int rt_term(void);
> >
> > __attribute__((__constructor__)) void dinit(void) {
> >  rt_init();
> > }
> > __attribute__((__destructor__)) void dterm(void) {
> >  rt_term();
> > }
> > ---
> >
> > The C runtime will initialise the D runtime for you.
> 
> That's a neat trick.
[...]

Indeed!

Though I'm not sure what will happen if your C program tries loading two
or more D libraries that use this trick... is rt_init() idempotent? If
not, it could lead to a fun mess on startup... :-D  It also doesn't
address the very thorny issue of how to make multiple D libraries work
nicely with each other's copy of druntime, or how to make them share a
single druntime.


T

-- 
Без труда не выловишь и рыбку из пруда. 


Re: Can I create static c callable library?

2018-09-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, September 27, 2018 6:16:13 AM MDT Atila Neves via Digitalmars-
d-learn wrote:
> On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg
>
> wrote:
> > On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis
> >
> > wrote:
> >> If you use -betterC, then it's trivial, because your D program
> >> is restricted to extern(C) functions and features which don't
> >> require druntime. It can also be done without -betterC (and
> >> thus with druntime), but it gets to be _way_ more of a pain,
> >> because it requires that you manually initialize druntime -
> >> either by forcing whatever is using your "C" library to call a
> >> specific function to initialize druntime before using any of
> >> its normal functions or by having every function in the
> >> library check whether druntime has been initialized yet and
> >> initialize it if it hasn't been before it does whatever it's
> >> supposed to do.
> >
> > Shouldn't it be possible to use a C initialization function,
> > i.e. pragma(crt_constructor) to initialize druntime? Then it
> > only needs to be initialized once and it's not required to
> > check if it's initialized all the time.
> >
> > --
> > /Jacob Carlborg
>
> Even easier, compile this C file and add the resulting object
> file to your (now mostly) D static library:
>
> ---
> extern int rt_init(void);
> extern int rt_term(void);
>
> __attribute__((__constructor__)) void dinit(void) {
>  rt_init();
> }
> __attribute__((__destructor__)) void dterm(void) {
>  rt_term();
> }
> ---
>
> The C runtime will initialise the D runtime for you.

That's a neat trick.

- Jonathan M Davis





Re: Can I create static c callable library?

2018-09-27 Thread Atila Neves via Digitalmars-d-learn
On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg 
wrote:
On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis 
wrote:


If you use -betterC, then it's trivial, because your D program 
is restricted to extern(C) functions and features which don't 
require druntime. It can also be done without -betterC (and 
thus with druntime), but it gets to be _way_ more of a pain, 
because it requires that you manually initialize druntime - 
either by forcing whatever is using your "C" library to call a 
specific function to initialize druntime before using any of 
its normal functions or by having every function in the 
library check whether druntime has been initialized yet and 
initialize it if it hasn't been before it does whatever it's 
supposed to do.


Shouldn't it be possible to use a C initialization function, 
i.e. pragma(crt_constructor) to initialize druntime? Then it 
only needs to be initialized once and it's not required to 
check if it's initialized all the time.


--
/Jacob Carlborg


Even easier, compile this C file and add the resulting object 
file to your (now mostly) D static library:


---
extern int rt_init(void);
extern int rt_term(void);

__attribute__((__constructor__)) void dinit(void) {
rt_init();
}
__attribute__((__destructor__)) void dterm(void) {
rt_term();
}
---

The C runtime will initialise the D runtime for you.



Re: Can I create static c callable library?

2018-09-26 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 26 September 2018 at 09:54:22 UTC, John Burton 
wrote:


Is there any documentation anywhere that deals with calling D 
from C? I could find plenty the other way round. I think I'll 
give up on the idea though, and rewrite the whole thing in D :)


Rewriting it in D is a great idea ;) But for the record, much of 
what you've read about calling C from D applies the other way, 
too. You just need to write your D functions as extern(C), 
following the same approach to function signatures and types as 
you've read about, then declare the crossover functions and types 
in C.


One gotcha to look out for is when you call a D function that 
allocates GC memory. In that case, you need to keep a reference 
to it alive on the D side. If it's only being allocated for use 
in C, you can call GC.addRoot [1] when you allocate the memory on 
the D side and GC.removeRoot [2] when you no longer need it.


Also keep in mind that D variables thread-local, and if you need 
to access any of them in C from multiple threads they would 
better be declared as __gshared in D.


[1] https://dlang.org/phobos/core_memory.html#.GC.addRoot
[2] https://dlang.org/phobos/core_memory.html#.GC.removeRoot


Re: Can I create static c callable library?

2018-09-26 Thread John Burton via Digitalmars-d-learn
On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis 
wrote:

[...]


Thanks everyone.

Is there any documentation anywhere that deals with calling D 
from C? I could find plenty the other way round. I think I'll 
give up on the idea though, and rewrite the whole thing in D :)


Re: Can I create static c callable library?

2018-09-25 Thread 9il via Digitalmars-d-learn

On Tuesday, 25 September 2018 at 11:03:11 UTC, John Burton wrote:

I need to write a library to statically link into a c program.
Can I write this library in D?
Will I be able to use proper D abilities like gc? Obviously the 
public interface will need to be basic c callable functions...


I 'main' is a c program will this work?


Yes, for example https://github.com/libmir/mir-optim
It has *.cpp example.


Re: Can I create static c callable library?

2018-09-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 9/25/18 10:13 AM, Jacob Carlborg wrote:

On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis wrote:

If you use -betterC, then it's trivial, because your D program is 
restricted to extern(C) functions and features which don't require 
druntime. It can also be done without -betterC (and thus with 
druntime), but it gets to be _way_ more of a pain, because it requires 
that you manually initialize druntime - either by forcing whatever is 
using your "C" library to call a specific function to initialize 
druntime before using any of its normal functions or by having every 
function in the library check whether druntime has been initialized 
yet and initialize it if it hasn't been before it does whatever it's 
supposed to do.


Shouldn't it be possible to use a C initialization function, i.e. 
pragma(crt_constructor) to initialize druntime? Then it only needs to be 
initialized once and it's not required to check if it's initialized all 
the time.


I don't know if that's the right call. pragma(crt_constructor) tasks run 
*before* C main. If you are initializing the runtime, it means you are 
running D static ctors.


Since C initialization functions have no order to them, it's possible 
that some initialization functions in the D runtime are using 
uninitialized pieces of the C runtime. But of course, I'm not sure. I 
just wouldn't trust it if it were me. We don't test initializing the D 
runtime before C main is started (in which case, the C runtime is 
guaranteed to be set up).


Does anyone know if the C runtime is set up before these functions are 
run? Is it guaranteed?


-Steve


Re: Can I create static c callable library?

2018-09-25 Thread Jacob Carlborg via Digitalmars-d-learn
On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis 
wrote:


If you use -betterC, then it's trivial, because your D program 
is restricted to extern(C) functions and features which don't 
require druntime. It can also be done without -betterC (and 
thus with druntime), but it gets to be _way_ more of a pain, 
because it requires that you manually initialize druntime - 
either by forcing whatever is using your "C" library to call a 
specific function to initialize druntime before using any of 
its normal functions or by having every function in the library 
check whether druntime has been initialized yet and initialize 
it if it hasn't been before it does whatever it's supposed to 
do.


Shouldn't it be possible to use a C initialization function, i.e. 
pragma(crt_constructor) to initialize druntime? Then it only 
needs to be initialized once and it's not required to check if 
it's initialized all the time.


--
/Jacob Carlborg


Re: Can I create static c callable library?

2018-09-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, September 25, 2018 5:03:11 AM MDT John Burton via Digitalmars-d-
learn wrote:
> I need to write a library to statically link into a c program.
> Can I write this library in D?
> Will I be able to use proper D abilities like gc? Obviously the
> public interface will need to be basic c callable functions...
>
> I 'main' is a c program will this work?

If you use -betterC, then it's trivial, because your D program is restricted
to extern(C) functions and features which don't require druntime. It can
also be done without -betterC (and thus with druntime), but it gets to be
_way_ more of a pain, because it requires that you manually initialize
druntime - either by forcing whatever is using your "C" library to call a
specific function to initialize druntime before using any of its normal
functions or by having every function in the library check whether druntime
has been initialized yet and initialize it if it hasn't been before it does
whatever it's supposed to do. And of course, if you pass any GC-allocated
memory out of the library, you have to worry about calling all of the
appropriate GC functions so that it knows not to free it and knowing when to
tell the GC that that memory can be freed. It's all very feasible and all
very annoying. In general, it's far, far easier to write D programs that
call into C code than to write C programs that call into D code. That's part
of why some folks are so excited about -betterC. It makes it _way_ easier to
write D libraries that can be called from C or C++ - though because you lose
out on so many D features in the process (like the GC), whether it's even
worth it is highly debatable.

- Jonathan M Davis





Can I create static c callable library?

2018-09-25 Thread John Burton via Digitalmars-d-learn

I need to write a library to statically link into a c program.
Can I write this library in D?
Will I be able to use proper D abilities like gc? Obviously the 
public interface will need to be basic c callable functions...


I 'main' is a c program will this work?