Re: DMD: How to compile executable without producing .obj file?

2023-11-09 Thread Inkrementator via Digitalmars-d-learn

On Sunday, 5 November 2023 at 18:58:48 UTC, BoQsc wrote:
When you compile using `dmd` compiler you will often get `.exe` 
and `.obj` file.


I would like to only produce `.exe` file:


On linux, gdc automatically cleans up object files by default. 
Passing it the -pipe option will prevent their creation in the 
first place. Maybe it will have the same behaviour on windows.




Re: D: How would one make a shared dynamically linked D library?

2023-11-09 Thread IchorDev via Digitalmars-d-learn

On Wednesday, 8 November 2023 at 11:48:58 UTC, BoQsc wrote:
I would like to export some functionality as external shared 
dynamically linked D library.


Is it possible to do that in D Language


Yes, as long as the symbols you want to use externally are 
`public`, which is the default.
When it comes to linking, the main factor is usually matching 
symbol mangling. In C you would help users do this by 
distributing your header files. In D it's more common to 
distribute your source code, so if you want to distribute a 
"header" you'll need to remove your function bodies:

```d
//regular function:
int add(int x, int y) nothrow{
  x += y;
  return x;
}

//for a D "header":
int add(int x) nothrow;
```


what are limitations?


The desired template instantiations must be generated at compile 
time, not at link time. CTFE probably won't work.


Example of shared dynamic libraries depending on other shared 
dynamic libraries would be great as well.


There should be no material difference to using a shared library 
from an executable binary.


Re: "is not an lvalue" when passing template function to spawn function

2023-11-09 Thread Bienlein via Digitalmars-d-learn

On Thursday, 9 November 2023 at 10:14:46 UTC, Bienlein wrote:

On Thursday, 9 November 2023 at 09:40:47 UTC, Bienlein wrote:
On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus 
wrote:

On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
...
The actual problem here is that you can't take the address of 
a template without instantiating it first. To make your 
example work, replace `&addToBiz` with `&addToBiz!int`, like 
this:


spawn(&addToBiz!int, biz);




All right. It seems I cannot pass on an object. So I store the 
object in a global and access it from the callback function 
passed to spawn.




Re: DMD: How to compile executable without producing .obj file?

2023-11-09 Thread Kagamin via Digitalmars-d-learn
The .exe is produced by the linker, which works with files: it 
takes one or more .obj files with program code and links them 
into and .exe file. I heard ldc has builtin linker or something 
like that, so hypothetically might be able to link on the fly.


Re: "is not an lvalue" when passing template function to spawn function

2023-11-09 Thread Bienlein via Digitalmars-d-learn

On Thursday, 9 November 2023 at 09:40:47 UTC, Bienlein wrote:
On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus 
wrote:

On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
...
The actual problem here is that you can't take the address of 
a template without instantiating it first. To make your 
example work, replace `&addToBiz` with `&addToBiz!int`, like 
this:


spawn(&addToBiz!int, biz);


Thanks, Paul. This helped a step further. When applying your 
change it looks like this:


Biz!int biz = new Biz!int(123);
spawn(&addToBiz!int, biz);

Then I get this error: 'Error: static assert:  "Aliases to 
mutable thread-local data not allowed."'


For this error I found this in the Internet: 
https://stackoverflow.com/questions/14395018/aliases-to-mutable-thread-local-data-not-allowed


But this change, did not help:

spawn(&addToBiz!int, cast(shared) biz);

Then I moved "Biz!int biz = new Biz!int(123);" out of the main 
function. Compiler complains about static this. Okay, then the 
code outside the main function now looks this way:



class Biz(T) {

private T value;

this(T value) {
this.value = value;
}

}

static void addToBiz(T)(Biz!T biz)
{
// ...
}


Biz!int biz;

static this() {
biz = new Biz!int(123);
}



int main()
{
   // ...
}

However, this results in no gain as the compiler now shows the 
initial error again: 'Error: static assert:  "Aliases to 
mutable thread-local data not allowed."'


Everything I tried on my own was also to no avail. If someone 
could gould give me a hint again ... ;-)


Thank you.


If I supply a callback function with the parameter not being an 
instance from a parameterized class I get the same error. The 
problem seems to be that the parameter of the callback function 
takes on object as a parameter and not a built-in type like int 
or String.


The samples on how to use the spawn function on dlang.org does 
not contain a sample on how to get things to work with a objecgt 
being supllied as parameter to the callback function


Re: Translating C precompiler macros to D

2023-11-09 Thread evilrat via Digitalmars-d-learn
On Wednesday, 8 November 2023 at 20:43:21 UTC, solidstate1991 
wrote:
Here's this precompiler macro from Pipewire, on which many 
important inline functions depend on, like this one:


```c
/**
 * Invoke method named \a method in the \a callbacks.
 * The \a method_type defines the type of the method struct.
 * Returns true if the method could be called, false otherwise.
 */
#define spa_callbacks_call(callbacks,type,method,vers,...)  
\
({  
\
const type *_f = (const type *) (callbacks)->funcs;  \
bool _res = SPA_CALLBACK_CHECK(_f,method,vers); 
\
if (SPA_LIKELY(_res))   
\
_f->method((callbacks)->data, ## __VA_ARGS__);  
  \
_res;   
\
})
```

So far, the only way out I see is to turn it into a string 
mixin. (SPA_LIKELY is just a needless precompiler macro for 
labeling things.)


Not sure if it will work in real situations, expect memory errors.
Also I used a fixed type, you should use CTFE to cast data to 
proper function argument types.



```d
import std.stdio;

bool SPA_CALLBACK_CHECK(T)(const (T)* f, string method, uint 
version_)

{
// do some checks...
return true;
}

bool spa_callbacks_call(alias callbacks, alias type, alias 
method, uint vers, Args...)(Args)

{
const (type)* _f = cast(type*) callbacks.funcs;
	bool _res = SPA_CALLBACK_CHECK(_f, __traits(identifier, method), 
vers);

if (_res)
		__traits(getMember, _f, __traits(identifier, method))(cast(int) 
callbacks.data, Args); // callback call

return _res;
}

// your callback, see pipewire docs for real examples
struct Foo
{
void bar(int x) const { import std.stdio; writeln(x);  }
}

// pipewire internals
struct spa_callback
{
const(void)* funcs;
void* data;
}


void main()
{
Foo foo;
	// instead of this naive approach you should use provided 
initialization method
	// but roughly first parameter is pointer to struct of function 
pointers

spa_callback cb = { cast(void*) &foo, cast(void*) 42 };
spa_callbacks_call!(cb, Foo, Foo.bar, 0)();
}
```


Re: "is not an lvalue" when passing template function to spawn function

2023-11-09 Thread Bienlein via Digitalmars-d-learn

On Wednesday, 8 November 2023 at 16:47:02 UTC, Paul Backus wrote:

On Wednesday, 8 November 2023 at 16:30:49 UTC, Bienlein wrote:
...
The actual problem here is that you can't take the address of a 
template without instantiating it first. To make your example 
work, replace `&addToBiz` with `&addToBiz!int`, like this:


spawn(&addToBiz!int, biz);


Thanks, Paul. This helped a step further. When applying your 
change it looks like this:


Biz!int biz = new Biz!int(123);
spawn(&addToBiz!int, biz);

Then I get this error: 'Error: static assert:  "Aliases to 
mutable thread-local data not allowed."'


For this error I found this in the Internet: 
https://stackoverflow.com/questions/14395018/aliases-to-mutable-thread-local-data-not-allowed


But this change, did not help:

spawn(&addToBiz!int, cast(shared) biz);

Then I moved "Biz!int biz = new Biz!int(123);" out of the main 
function. Compiler complains about static this. Okay, then the 
code outside the main function now looks this way:



class Biz(T) {

private T value;

this(T value) {
this.value = value;
}

}

static void addToBiz(T)(Biz!T biz)
{
// ...
}


Biz!int biz;

static this() {
biz = new Biz!int(123);
}



int main()
{
   // ...
}

However, this results in no gain as the compiler now shows the 
initial error again: 'Error: static assert:  "Aliases to mutable 
thread-local data not allowed."'


Everything I tried on my own was also to no avail. If someone 
could gould give me a hint again ... ;-)


Thank you.