Thread overview
Using ImportC to augment a big C project with D
February 20

I just saw the announcement that macros with parameters are now translated into D by ImportC. Incredible! Congratulations to all involved.

As an occasional D user, I have long wanted a fast route to using D with an existing large C project (100K lines approximately).

I want to replace the C main program with a D main function that calls the old C main function (suitably renamed) to change the command line arguments that can be supplied, and with the helpful side effect that druntime is properly initialized. I want to replace some C files with D ones. (I am cognizant of GC issues here, this is not what I am asking about.)

Now I can use ImportC with all of the header files to make the D replacement files easy to write correctly. Perhaps I can use ImportC for all of the C source.

When the resulting executable runs it will have D call C which in turn calls D. In that last D (the D files replacing some C files), if I throw an exception and don't catch it in the D files that replace some C files, will it propagate correctly to the D main function where I can catch it?

The C source calls exit() from C's stdlib, and D needs to terminate properly. Throwing an exception and catching it in D's main function seems to be a way to achieve this. What is the best way to deal with exit() ?

I want to use D's remarkable Fiber class to reimplement a deterministic stack changing context switch that in the original project is achieved with assembly code on a per-platform basis. This will mean that D's main function will call C which will call D which will effect a context switch. Is there any reason to believe this will work as naively hoped?

February 21

On Tuesday, 20 February 2024 at 18:33:42 UTC, Carl Sturtivant wrote:

>

The C source calls exit() from C's stdlib, and D needs to terminate properly.

What do you mean by "need"? You can call https://dlang.org/phobos/core_stdc_stdlib.html#.exit from D:

import std.stdio;

void main()
{
    scope(exit) writeln("Bye");

    import core.stdc.stdlib : exit;
    exit(0);
}

shared static ~this()
{
    writeln(__FUNCTION__);
}

Output:

onlineapp._sharedStaticDtor_L11_C1

So it does run module destructors, but not scope(exit) statements (which probably makes sense).

I would expect exit() called from the C source to have similar results.

--Bastiaan

February 21

On Wednesday, 21 February 2024 at 12:45:50 UTC, Bastiaan Veelo wrote:

>

What do you mean by "need"? You can call https://dlang.org/phobos/core_stdc_stdlib.html#.exit from D:

Of course, but does it respect D shutdown?

>

Output:

onlineapp._sharedStaticDtor_L11_C1

So it does run module destructors, but not scope(exit) statements (which probably makes sense).

So it doesn't respect D shutdown, i.e. what happens when returning from main with an error code.

>

I would expect exit() called from the C source to have similar results.

Why is that?

I just found this.
Proper way to exit with specific exit code?

February 21

On Tuesday, 20 February 2024 at 18:33:42 UTC, Carl Sturtivant wrote:

>

When the resulting executable runs it will have D call C which in turn calls D. In that last D (the D files replacing some C files), if I throw an exception and don't catch it in the D files that replace some C files, will it propagate correctly to the D main function where I can catch it?

My understanding is that this reply indicates that this works. Exceptions thrown by D can be caught by D in general in the presence of ImportC.

>

The C source calls exit() from C's stdlib, and D needs to terminate properly. Throwing an exception and catching it in D's main function seems to be a way to achieve this. What is the best way to deal with exit() ?

So I can simulate C's exit() by throwing an exception and catching it in main() as suggested here.

>

I want to use D's remarkable Fiber class to reimplement a deterministic stack changing context switch that in the original project is achieved with assembly code on a per-platform basis. This will mean that D's main function will call C which will call D which will effect a context switch. Is there any reason to believe this will work as naively hoped?

I'll have to proceed experimentally, but I'd like to know in advance if this is doomed. Anyone?