Re: Function Pointer

2023-08-31 Thread vino via Digitalmars-d-learn

On Wednesday, 30 August 2023 at 21:12:57 UTC, Paul Backus wrote:

On Wednesday, 30 August 2023 at 17:48:19 UTC, Vino wrote:

Hi All,

 Request your help on hot to create a pointer for a function 
whose function type is Result.


```
ReturnType!(typeof()).stringof; // Result

From
Vino
```


To get a function pointer type from a function type, you can 
add `*` on the end:


void func(int) {}

alias FuncType = typeof(func);
pragma(msg, FuncType); // void(int)

alias FuncPtrType = FuncType*;
pragma(msg, FuncPtrType); // void function(int)
static assert(is(FuncPtrType == typeof()));


Thank you very much


Re: Function Pointer

2023-08-30 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 30 August 2023 at 17:48:19 UTC, Vino wrote:

Hi All,

 Request your help on hot to create a pointer for a function 
whose function type is Result.


```
ReturnType!(typeof()).stringof; // Result

From
Vino
```


To get a function pointer type from a function type, you can add 
`*` on the end:


void func(int) {}

alias FuncType = typeof(func);
pragma(msg, FuncType); // void(int)

alias FuncPtrType = FuncType*;
pragma(msg, FuncPtrType); // void function(int)
static assert(is(FuncPtrType == typeof()));


Re: How can a function pointer required to be extern(C)?

2023-04-13 Thread rempas via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 21:00:04 UTC, John Chapman wrote:


You can also express it like this:

```d
extern(C) alias FuncPtr = void* function(void*);
```


Thank you! This is how I was planning to do anyway because other 
that the fact that I like the syntax of that a little bit more, 
this code will be part of the library so there will not be any 
function to take its type so I cannot do this the other away even 
if I wanted. Have an amazing day my friend!


Re: How can a function pointer required to be extern(C)?

2023-04-13 Thread rempas via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 20:36:59 UTC, H. S. Teoh wrote:


IMO this is a bug either in D's syntax or in the parser.  I'd 
file an enhancement request.


In the meantime, you can use alias as a workaround:


---snip---
extern(C) void* abc(void*) {return null;}

alias FuncPtr = typeof();
pragma(msg, typeof(abc));
pragma(msg, typeof());

//void wrapper(extern(C) void* function(void*) callback) {} // 
NG

void wrapper(FuncPtr callback) {} // OK

pragma(msg, typeof(wrapper));
---snip---


T


Thank you! As long as there is a way to do it with aliases, I 
don't think that there is a reason to even bother the developers. 
I mean, it will just save me 1 line of code in my whole project 
(because I don't think I'll use this even again somewhere else) 
so I don't think it's worth it. Thank you for your help. Best 
thing with Dlang is the community ;) I wish you to have an 
amazing day!




Re: How can a function pointer required to be extern(C)?

2023-04-12 Thread John Chapman via Digitalmars-d-learn

On Wednesday, 12 April 2023 at 20:36:59 UTC, H. S. Teoh wrote:

---snip---
extern(C) void* abc(void*) {return null;}

alias FuncPtr = typeof();


You can also express it like this:

```d
extern(C) alias FuncPtr = void* function(void*);
```


Re: How can a function pointer required to be extern(C)?

2023-04-12 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Apr 12, 2023 at 08:23:51PM +, rempas via Digitalmars-d-learn wrote:
> Sorry if the title doesn't make any sense, let me explain. So, I do have the
> following code that does not compile:
> 
> ```d
> import core.sys.posix.pthread; /* The library */
> 
> struct Thread {
> private:
>   pthread_t thread_id;
> 
> public:
>   this(void* function(void*) func, void* arg = null, scope
> const(pthread_attr_t*) attr = null) {
> pthread_create(_id, attr, func, arg);
>   }
> 
>   @property:
> pthread_t id() { return this.thread_id; }
> }
> 
> ```
> 
> Yes, I'm trying to "encapsulate" the Pthread (POSIX threads) API.
> Normally, the function pointer that is passed to "pthread_create" must
> be "extern(C)" and this is the complaining that the compile does. So,
> I'm thinking to replace the constructor to this:
> 
> ```d
> this(extern(C) void* function(void*) func, void* arg = null,
>  scope const(pthread_attr_t*) attr = null)
> { pthread_create(_id, attr, func, arg); }
> ```
> 
> I just added "extern(C)" before the type. This is how it looks in the
> error message so it must work right? Well... it doesn't. And here I am
> wondering why. Any ideas?

IMO this is a bug either in D's syntax or in the parser.  I'd file an
enhancement request.

In the meantime, you can use alias as a workaround:


---snip---
extern(C) void* abc(void*) {return null;}

alias FuncPtr = typeof();
pragma(msg, typeof(abc));
pragma(msg, typeof());

//void wrapper(extern(C) void* function(void*) callback) {} // NG
void wrapper(FuncPtr callback) {} // OK

pragma(msg, typeof(wrapper));
---snip---


T

-- 
A programming language should be a toolbox for the programmer to draw
upon, not a minefield of dangerous explosives that you have to very
carefully avoid touching in the wrong way.


How can a function pointer required to be extern(C)?

2023-04-12 Thread rempas via Digitalmars-d-learn
Sorry if the title doesn't make any sense, let me explain. So, I 
do have the following code that does not compile:


```d
import core.sys.posix.pthread; /* The library */

struct Thread {
private:
  pthread_t thread_id;

public:
  this(void* function(void*) func, void* arg = null, scope 
const(pthread_attr_t*) attr = null) {

pthread_create(_id, attr, func, arg);
  }

  @property:
pthread_t id() { return this.thread_id; }
}

```

Yes, I'm trying to "encapsulate" the Pthread (POSIX threads) API. 
Normally, the function pointer that is passed to "pthread_create" 
must be "extern(C)" and this is the complaining that the compile 
does. So, I'm thinking to replace the constructor to this:


```d
this(extern(C) void* function(void*) func, void* arg = null,
 scope const(pthread_attr_t*) attr = null)
{ pthread_create(_id, attr, func, arg); }
```

I just added "extern(C)" before the type. This is how it looks in 
the error message so it must work right? Well... it doesn't. And 
here I am wondering why. Any ideas?


Re: Can't assign extern(C) function pointer to D variable?

2022-11-22 Thread XavierAP via Digitalmars-d-learn

On Tuesday, 22 November 2022 at 21:32:43 UTC, Hipreme wrote:


You need to create an alias containing your callback type.


Thanks both!! I have all the pieces of the puzzle. I'm actually 
staying with the wrapping template solution. (Because the 
strongly typed one turns out too convoluted, and because it 
allows the remaining ScopeCleanup struct to be more general 
purpose, for non-C functions, and for functions that don't return 
void but an error code which I want to discard.)


The first problem was indeed that a C function pointer "is not" a 
D one. So annotating the variable with extern(C) can indeed solve 
it. I had actually tried this, but it was not compiling for 
another reason.


The next reason (as you see in the GitHub link) is that the 
variable in question is a (constructor) parameter. D can't seem 
to compile extern(C) inlined somewhere else.


Indeed aliasing takes care of this second problem:

alias CFunction = extern(C) void function();

	/// RAII object that does nothing but calling, when destructed, 
the function passed at construction.

struct ScopeCleanup
{
@disable this();
this(CFunction cleanup) { this.cleanup = cleanup; }
~this() { cleanup(); }

CFunction cleanup;
}

Now this module compiles. BUT the code trying to call this 
constructor doesn't compile, when called with C function such as 
SDL_Quit imported from the SDL lib, or IMG_Quit imported from the 
SDL_image lib.


From the compiler error I learn that the imported function is not 
only extern(C) but also nothrow @nogc. Fair enough, I add it to 
the alias. BUT still no good, because (as I learn from the same 
compiler error) this binding imports these functions as


extern(C) void function() nothrow @nogc*

with this final "*" this turns out, from the D point of view, a 
"pointer to a function pointer" XD so it has to be 
called/de-referenced in this way (in destructor):


alias CFunctionPtr = extern(C) void function() nothrow @nogc*;

	/// RAII object that does nothing but calling, when destructed, 
the function passed at construction.

struct ScopeCleanup
{
@disable this();
this(CFunctionPtr cleanup) { this.cleanup = cleanup; }
~this() { (*cleanup)(); }

CFunctionPtr cleanup;
}

Thanks guys for the learning, I'm staying with the template 
solution (thanks D), but let me know if you have more insights.


Re: Can't assign extern(C) function pointer to D variable?

2022-11-22 Thread ag0aep6g via Digitalmars-d-learn

On 22.11.22 22:11, XavierAP wrote:
I was surprised when it didn't compile, though I immediately found it 
understandable...

Already read through https://dlang.org/spec/interfaceToC.html
and https://wiki.dlang.org/Bind_D_to_C

Is it really the case (that an extern(C) function pointer cannot be 
assigned to a D variable)? Or is it a matter of annotating with the 
right attributes? If so, how?


Works for me:

import core.stdc.stdio: puts;
auto p1 = 
extern (C) int function(const char* s) p2 = 

If you're trying to assign an `extern (C)` function pointer to an 
`extern (D)` one (the default), that cannot work. The compiler would 
emit code using D's calling convention, but the called function would 
assume C's calling convention.


Re: Can't assign extern(C) function pointer to D variable?

2022-11-22 Thread Hipreme via Digitalmars-d-learn

On Tuesday, 22 November 2022 at 21:11:37 UTC, XavierAP wrote:
I was surprised when it didn't compile, though I immediately 
found it understandable...

Already read through https://dlang.org/spec/interfaceToC.html
and https://wiki.dlang.org/Bind_D_to_C

[...]



You need to create an alias containing your callback type.

```d

alias DCallback = extern(C) void function();
DCallback cb;
cb = yourCFunction;
```


Can't assign extern(C) function pointer to D variable?

2022-11-22 Thread XavierAP via Digitalmars-d-learn
I was surprised when it didn't compile, though I immediately 
found it understandable...

Already read through https://dlang.org/spec/interfaceToC.html
and https://wiki.dlang.org/Bind_D_to_C

Is it really the case (that an extern(C) function pointer cannot 
be assigned to a D variable)? Or is it a matter of annotating 
with the right attributes? If so, how?


Otherwise I'm interested in the best or most concise workaround. 
Is there a better one? I came up with a template solution:


https://github.com/XavierAP/game-king/blob/master/source/scope_cleanup.d

The problem I had was that this ScopeCleanup struct could not be 
constructed passing a pointer to a function imported from C (from 
the SDL library; you can browse around the same repo to see its 
usage; it's just a toy project that's barely started).


Re: function(pointer) as template argument, explicit template instantiation

2021-12-31 Thread kdevel via Digitalmars-d-learn

On Friday, 31 December 2021 at 12:36:46 UTC, H. S. Teoh wrote:

```
void lyr(alias Fn)(ref R r)
{
Fn(r);
}
```


Thanks! That helped me reinvent the engine.



Re: function(pointer) as template argument, explicit template instantiation

2021-12-31 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Dec 31, 2021 at 11:52:21AM +, kdevel via Digitalmars-d-learn wrote:
[...]
> That is what I want to do. The function template lyr shall be
> (explicitly) instantiated in order to put the resulting function
> pointer into an AA. The call signature of lyr!(foo) and foo must be
> the same.
> 
> In C++ this looks like this:
[...]


struct R {}

void lyr(alias Fn)(ref R r)
{
Fn(r);
}

void foo(ref R r) { }

static immutable void function(ref R)[string] reg;
shared static this() {
// workaround for lack of CT AA initialization
reg = [
"foo": ,
"lfoo": !foo,
];
}



T

-- 
Why waste time reinventing the wheel, when you could be reinventing the engine? 
-- Damian Conway


Re: function(pointer) as template argument, explicit template instantiation

2021-12-31 Thread kdevel via Digitalmars-d-learn
On Friday, 31 December 2021 at 09:01:10 UTC, data pulverizer 
wrote:

On Friday, 31 December 2021 at 00:57:26 UTC, kdevel wrote:
Pointers are runtime entities and are not suitable template 
parameters (compile time).


The address of a function does not change at runtime. The 
question is: Can functions (pointers) be used as template 
arguments?


So assuming that you are trying to either pass a function 
constant of a specific type signature as a template argument,


That is what I want to do. The function template lyr shall be 
(explicitly) instantiated in order to put the resulting function 
pointer into an AA. The call signature of lyr!(foo) and foo must 
be the same.


In C++ this looks like this:

```C++
struct R {
};

// typedef void (* Fn) (R &); // ptr version
typedef void (& Fn) (R &);

template
static void lyr (R )
{
   // invoke f
}

static void foo (R )
{
}

/* ptr version
static const std::map reg = {
   {"foo", },
   {"lfoo", } // <--- func tmpl instantiation
};
*/

static const std::map reg = {
   {"foo", foo},
   {"lfoo", lyr} // <--- func tmpl instantiation
};
```




Re: function(pointer) as template argument, explicit template instantiation

2021-12-31 Thread kdevel via Digitalmars-d-learn

On Friday, 31 December 2021 at 03:02:08 UTC, Tejas wrote:
[...]
Is it okay to use template parameter instead of **template 
value** parameter?

```d
class R {
}

void foo (R r)
{
}

void lyr (fp_type, R) (fp_type fp, R r)
{
}

pragma (msg, typeof ());
R r;
void main(){
auto foo_ptr = 
lyr(foo_ptr, r);
}
```


No, the type should be the same. I want to register lyr!() 
like this:


```
   fn [string] reg = [
  "foo": ,
  "lfoo": !()
   ];
```


Re: function(pointer) as template argument, explicit template instantiation

2021-12-31 Thread data pulverizer via Digitalmars-d-learn

On Friday, 31 December 2021 at 00:57:26 UTC, kdevel wrote:

```dptr.d
class R {
}

void foo (R r)
{
}

alias fn = void function (R);

void lyr (fn F) (R r)
{
}

immutable fn foo_ptr =  // line 14
pragma (msg, typeof (foo_ptr));

auto ptr = lyr!(foo_ptr);// line 17
```
dmd reports:

```
immutable(void function(R))
dptr.d(14): Error: expression `& foo` is not a valid template 
value argument

```

If I comment out line 17 the code compiles. I want to put the 
explicitly instantiated function template into an immutable AA. 
How can that be phrased such that dmd compiles it?


Pointers are runtime entities and are not suitable template 
parameters (compile time).


So assuming that you are trying to either pass a function 
constant of a specific type signature as a template argument, or 
a function pointer as an argument with either a template 
specialisation or constraint:



```
class R {}
void foo(R r){}
alias fn = void function(R);

//function compile time constant
void lyr(fn fp_type)(R r){}

//As template constraint
void con(T)(T fun, R r)
if(is(T == fn))
{
  fun(r);
}

/*
  //As template specialisation
  void con(T: fn)(T fun, R r)
  {
fun(r);
  }
*/

//Function constant
enum fn foo_ptr = (R r){};
pragma(msg, typeof(foo_ptr));

//Declared at compile time but only executable at runtime
auto ptr = !(foo_ptr);

void main()
{
  //auto ptr = !(foo_ptr);//could declare this here
  ptr(new R());
  fn new_ptr = 
  con(new_ptr, new R());
}

```


Re: function(pointer) as template argument, explicit template instantiation

2021-12-30 Thread Tejas via Digitalmars-d-learn

On Friday, 31 December 2021 at 00:57:26 UTC, kdevel wrote:

```dptr.d
class R {
}

void foo (R r)
{
}

alias fn = void function (R);

void lyr (fn F) (R r)
{
}

immutable fn foo_ptr =  // line 14
pragma (msg, typeof (foo_ptr));

auto ptr = lyr!(foo_ptr);// line 17
```
dmd reports:

```
immutable(void function(R))
dptr.d(14): Error: expression `& foo` is not a valid template 
value argument

```

If I comment out line 17 the code compiles. I want to put the 
explicitly instantiated function template into an immutable AA. 
How can that be phrased such that dmd compiles it?


Is it okay to use template parameter instead of **template 
value** parameter?

```d
class R {
}

void foo (R r)
{
}

void lyr (fp_type, R) (fp_type fp, R r)
{
}

pragma (msg, typeof ());
R r;
void main(){
auto foo_ptr = 
lyr(foo_ptr, r);
}
```


function(pointer) as template argument, explicit template instantiation

2021-12-30 Thread kdevel via Digitalmars-d-learn

```dptr.d
class R {
}

void foo (R r)
{
}

alias fn = void function (R);

void lyr (fn F) (R r)
{
}

immutable fn foo_ptr =  // line 14
pragma (msg, typeof (foo_ptr));

auto ptr = lyr!(foo_ptr);// line 17
```
dmd reports:

```
immutable(void function(R))
dptr.d(14): Error: expression `& foo` is not a valid template 
value argument

```

If I comment out line 17 the code compiles. I want to put the 
explicitly instantiated function template into an immutable AA. 
How can that be phrased such that dmd compiles it?


Re: How to do a function pointer to "malloc" and "free"?

2021-10-17 Thread Adam Ruppe via Digitalmars-d-learn

On Sunday, 17 October 2021 at 23:07:15 UTC, Elmar wrote:
Do you have a link for more information how to initialize the D 
runtime?


Export a function that calls this:
http://druntime.dpldocs.info/core.runtime.Runtime.initialize.html

And also export a function that calls this:
http://druntime.dpldocs.info/core.runtime.Runtime.terminate.html

And tell the user to call those when they load/unload the 
library. (It is pretty common for C libraries to require explicit 
init/term calls so they should be used to it.)


They refcount internally so it is ok to call multiple times, just 
make sure the init and term are always paired.




(btw the druntime actually exports them as extern(C) 
rt_init/rt_term but I'd still recommend you do your own anyway. 
if you do have extra work to do you can just do it there, and it 
can use whatever your lib naming conventions are. and besides im 
not sure if the extern(C) things are specified stable (even 
though they have been for as long as i can remember), whereas 
doing your own thing that `import core.runtime; return 
Runtime.initalize;` is. )


Re: How to do a function pointer to "malloc" and "free"?

2021-10-17 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 17:14:30 UTC, Adam Ruppe wrote:

On Sunday, 10 October 2021 at 13:52:57 UTC, Elmar wrote:
The language subset "BetterC" is required for calling D 
functions from C though.


This is false.

You can use any D features when calling it from C, you just 
need to provide an init and term function that is called from C 
that runtime initialize and terminate for the full experience.



BetterC helper librarys like Tanya or Tango do exist.


I don't know tanya, but Tango has absolutely nothing to do with 
betterC. It is a set of classes that use the full runtime.


That's nice!

Do you have a link for more information how to initialize the D 
runtime? I just wondered about that because I thought it actually 
shouldn't be much more difficult than just linking the runtime 
into the foreign-language compiled program. I didn't find 
information on that. Maybe I didn't search long enough.


Re: How to do a function pointer to "malloc" and "free"?

2021-10-11 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/10/21 6:44 AM, rempas wrote:

I'm having the following C code:

```
static void* (*ppmalloc)(size_t) = malloc;
static void (*ppfree)(void*) = free;
```

I want to covert this code in D so I try to do the following:

```
static void* function(size_t)*ppmalloc = malloc;
static void  function(void*)*ppfree = free;
```

If I do that, I'm getting the following error message:

```
Error: function `core.stdc.stdlib.malloc(ulong size)` is not callable 
using argument types `()`

```

I'm also trying to do the same using "pureMalloc" and "pureFree" instead 
but this time I'm getting the following error:


```
cannot implicitly convert expression `pureMalloc()(size_t size)` of type 
`void` to `extern (C) void* function(ulong)*`

```

Any ideas?


I know most of this is answered already, but I would suggest actually just:

```d
auto ppmalloc = 
```

which all of D's type inference to allow you to declare the appropriate 
function type.


BTW, you get the error because in D, empty parentheses are optional. So 
when you say `malloc`, it really means `malloc()`. Which is one big 
reason why the & operator is required.


-Steve


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread rempas via Digitalmars-d-learn

On Sunday, 10 October 2021 at 14:00:37 UTC, Elmar wrote:

On Sunday, 10 October 2021 at 13:56:06 UTC, rempas wrote:


Actually I know about BetterC and how to call C functions from 
D and visa versa. I would also disagree that "BetterC" is 
almost no improvement over C as about 90% of the language is 
there!! C++ classes are also supported


Nice :-) , you're right. I need to be more optimistic here. 
Happy coding.


Thanks a lot! Happy coding to you too!


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread Adam Ruppe via Digitalmars-d-learn

On Sunday, 10 October 2021 at 13:52:57 UTC, Elmar wrote:
The language subset "BetterC" is required for calling D 
functions from C though.


This is false.

You can use any D features when calling it from C, you just need 
to provide an init and term function that is called from C that 
runtime initialize and terminate for the full experience.



BetterC helper librarys like Tanya or Tango do exist.


I don't know tanya, but Tango has absolutely nothing to do with 
betterC. It is a set of classes that use the full runtime.


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 13:56:06 UTC, rempas wrote:


Actually I know about BetterC and how to call C functions from 
D and visa versa. I would also disagree that "BetterC" is 
almost no improvement over C as about 90% of the language is 
there!! C++ classes are also supported


Nice :-) , you're right. I need to be more optimistic here. Happy 
coding.


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 13:52:57 UTC, Elmar wrote:


The language subset "BetterC" is required for calling D 
functions from C though. Unfortunately, the runtime features of 
BetterC are limited and some of C's language features aren't 
availabe like C99 variable-length-arrays. "BetterC" is like 
programming in C with little more comfort but phobos is 
unusable which makes BetterC almost no improvement over C. 
BetterC helper librarys like Tanya or Tango do exist.




Oh well, I could also be wrong with BetterC support of Tanya and 
Tango but both are alterantives to Phobos.


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread rempas via Digitalmars-d-learn

On Sunday, 10 October 2021 at 13:52:57 UTC, Elmar wrote:


Hopefully it will :-) .

D has some good C support. You can call any C function from `D` 
by declaring it `extern(C) `.


The language subset "BetterC" is required for calling D 
functions from C though. Unfortunately, the runtime features of 
BetterC are limited and some of C's language features aren't 
availabe like C99 variable-length-arrays. "BetterC" is like 
programming in C with little more comfort but phobos is 
unusable which makes BetterC almost no improvement over C. 
BetterC helper librarys like Tanya or Tango do exist.


In that case it can indeed be better for you to convert the 
program's entry point into D code. This is unfortunate because 
it prevents C code bases from using D.


There is a tool [C++ Conversion 
Wizard](https://rainers.github.io/visuald/visuald/CppConversion.html) which could be able to convert C++ and C to D but I don't know how good it is and whether it's usable for free on a GNU/Linux derivative OS. It's only half-automatic.


Actually I know about BetterC and how to call C functions from D 
and visa versa. I would also disagree that "BetterC" is almost no 
improvement over C as about 90% of the language is there!! C++ 
classes are also supported


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 13:10:27 UTC, rempas wrote:


Thanks, I'm converting a library from C to D so I have to fix 
all the other bugs first to see If it's working but probably it 
will. Have an amazing day my friend!


Hopefully it will :-) .

D has some good C support. You can call any C function from `D` 
by declaring it `extern(C) `.


The language subset "BetterC" is required for calling D functions 
from C though. Unfortunately, the runtime features of BetterC are 
limited and some of C's language features aren't availabe like 
C99 variable-length-arrays. "BetterC" is like programming in C 
with little more comfort but phobos is unusable which makes 
BetterC almost no improvement over C. BetterC helper librarys 
like Tanya or Tango do exist.


In that case it can indeed be better for you to convert the 
program's entry point into D code. This is unfortunate because it 
prevents C code bases from using D.


There is a tool [C++ Conversion 
Wizard](https://rainers.github.io/visuald/visuald/CppConversion.html) which could be able to convert C++ and C to D but I don't know how good it is and whether it's usable for free on a GNU/Linux derivative OS. It's only half-automatic.


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread rempas via Digitalmars-d-learn

On Sunday, 10 October 2021 at 11:26:18 UTC, Elmar wrote:

Hello rempas.

This is the way:

```d
import core.stdc.stdlib : malloc, free;
extern(C) void* function(ulong) mallocPointer = 
extern(C) void function(void*) freePointer = 
```

`function` in the type is already a function pointer. Not 
immediately obvious though: You also must annotate the type 
with `extern(C)` otherwise it will not work.


Thanks, I'm converting a library from C to D so I have to fix all 
the other bugs first to see If it's working but probably it will. 
Have an amazing day my friend!


Re: How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread Elmar via Digitalmars-d-learn

On Sunday, 10 October 2021 at 10:44:15 UTC, rempas wrote:

I'm having the following C code:

```
static void* (*ppmalloc)(size_t) = malloc;
static void (*ppfree)(void*) = free;
```

I want to covert this code in D so I try to do the following:

```
static void* function(size_t)*ppmalloc = malloc;
static void  function(void*)*ppfree = free;
```

If I do that, I'm getting the following error message:

```
Error: function `core.stdc.stdlib.malloc(ulong size)` is not 
callable using argument types `()`

```

I'm also trying to do the same using "pureMalloc" and 
"pureFree" instead but this time I'm getting the following 
error:


```
cannot implicitly convert expression `pureMalloc()(size_t 
size)` of type `void` to `extern (C) void* function(ulong)*`

```

Any ideas?


Hello rempas.

This is the way:

```d
import core.stdc.stdlib : malloc, free;
extern(C) void* function(ulong) mallocPointer = 
extern(C) void function(void*) freePointer = 
```

`function` in the type is already a function pointer. Not 
immediately obvious though: You also must annotate the type with 
`extern(C)` otherwise it will not work.


How to do a function pointer to "malloc" and "free"?

2021-10-10 Thread rempas via Digitalmars-d-learn

I'm having the following C code:

```
static void* (*ppmalloc)(size_t) = malloc;
static void (*ppfree)(void*) = free;
```

I want to covert this code in D so I try to do the following:

```
static void* function(size_t)*ppmalloc = malloc;
static void  function(void*)*ppfree = free;
```

If I do that, I'm getting the following error message:

```
Error: function `core.stdc.stdlib.malloc(ulong size)` is not 
callable using argument types `()`

```

I'm also trying to do the same using "pureMalloc" and "pureFree" 
instead but this time I'm getting the following error:


```
cannot implicitly convert expression `pureMalloc()(size_t size)` 
of type `void` to `extern (C) void* function(ulong)*`

```

Any ideas?


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

I will wait with this code.
WaitForSingleObject(threading, INFINITE);


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

On Thursday, 19 November 2020 at 15:51:09 UTC, Kagamin wrote:
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


The thread that I do wait ultil function is finished. Using a 
while with 3 seconds to verify if thread id is in running list, 
and break if not finishing owner thread.


Re: Function Pointer Not Working

2020-11-19 Thread Kagamin via Digitalmars-d-learn
The delegate is stored on the stack of the calling thread, the 
created thread loads it from there, but the calling thread 
doesn't wait for that and clobbers the stack right away. If you 
were lucky your code would crash.


Re: Function Pointer Not Working

2020-11-19 Thread Marcone via Digitalmars-d-learn

Solved replacing this line:

CreateThread(null, 0, &_fun, , 0, null);

to this code:
task!({CreateThread(null, 0, &_fun, , 0, 
null);}).executeInNewThread();


Re: Function Pointer Not Working

2020-11-18 Thread Vladimir Panteleev via Digitalmars-d-learn

On Thursday, 19 November 2020 at 04:23:13 UTC, Marcone wrote:

// Function threadingw()
void threadingw(HWND hwn, void delegate() fun) nothrow {
try {
// Function _fun()
extern(Windows)
uint _fun(void * arg){
			(*(cast(void delegate()*) arg))(); // Do not show "Hello 
World!" :(

return 0;
}
CreateThread(null, 0, &_fun, , 0, null);
} catch(Throwable){}
}

void main(){
null.threadingw({writeln("Hello World!");});

}


A delegate is a "fat" pointer (function pointer + context), so it 
can't fit in a void*.


You could do something like the following to "uncurry" the 
delegate and extract its context to a void* and a regular 
function, which can then combine the void* given to it later to 
call the original delegate:


import std.traits;

auto uncurryDelegate(alias anchor, alias target)()
{
alias Args = Parameters!target;
alias R = ReturnType!target;

alias ContextPtr = void*;
alias Dg = typeof();

union Delegate
{
Dg dg;
struct
{
void* ptr;
void* funcptr;
}
}

auto dg = Delegate();
	__gshared void* funcptr; // Will always be the same for this 
instantiation

funcptr = ().funcptr;

static struct Result
{
R function(ContextPtr ptr, Args args) fun;
ContextPtr context;
}

static R fun(ContextPtr ptr, Args args)
{
Delegate dg;
dg.funcptr = funcptr;
dg.ptr = ptr;
return dg.dg(args);
}
return Result(, dg.ptr);
}

auto uncurryDelegate(alias target)()
{
return uncurryDelegate!(target, target);
}

unittest
{
int fun(int i)
{
return i + 1;
}
auto r = uncurryDelegate!fun;
assert(r.fun(r.context, 2) == 3);
}

unittest
{
struct S
{
int i;
int fun(int j)
{
return i + j;
}

auto funUncurried() { return uncurryDelegate!(i, fun); }
}
auto s = S(2);
auto r = s.funUncurried();
assert(r.fun(r.context, 3) == 5);
}

Sadly you can't write `static immutable void* funcptr = 
().funcptr;`, because the compiler tries to evaluate 
 first.


Alternatively you could do this (not recommended): 
https://stackoverflow.com/a/8656294/21501


Function Pointer Not Working

2020-11-18 Thread Marcone via Digitalmars-d-learn

// Function threadingw()
void threadingw(HWND hwn, void delegate() fun) nothrow {
try {
// Function _fun()
extern(Windows)
uint _fun(void * arg){
			(*(cast(void delegate()*) arg))(); // Do not show "Hello 
World!" :(

return 0;
}
CreateThread(null, 0, &_fun, , 0, null);
} catch(Throwable){}
}

void main(){
null.threadingw({writeln("Hello World!");});

}


Re: is function pointer least significant bit always zero ?

2018-10-27 Thread Ali Çehreli via Digitalmars-d-learn

On 10/27/2018 09:16 PM, learnfirst1 wrote:
I plan to use function pointer least significant bit to store some 
information.


If there is no GC on my system,  I think it will help the memory is well 
aligned.


The question is all the function least significant bit is zero ?

Most definitely. Related presentation:

  http://dconf.org/2016/talks/sechet.html

Ali


is function pointer least significant bit always zero ?

2018-10-27 Thread learnfirst1 via Digitalmars-d-learn
I plan to use function pointer least significant bit to store 
some information.


If there is no GC on my system,  I think it will help the memory 
is well aligned.


The question is all the function least significant bit is zero ?


Re: Checking if a function pointer is set or null

2018-04-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, April 09, 2018 00:25:08 solidstate1991 via Digitalmars-d-learn 
wrote:
> Would the if(!(myFunctionPointer is null)){} work is I
> intended?

You can also do

if(myFunctionPointer !is null)

- Jonathan M Davis



Re: Checking if a function pointer is set or null

2018-04-08 Thread Uknown via Digitalmars-d-learn

On Monday, 9 April 2018 at 00:25:08 UTC, solidstate1991 wrote:
Would the if(!(myFunctionPointer is null)){} work is I 
intended?


Yes, that works as you expect

https://run.dlang.io/is/ZTtm0P


Checking if a function pointer is set or null

2018-04-08 Thread solidstate1991 via Digitalmars-d-learn
Would the if(!(myFunctionPointer is null)){} work is I 
intended?


Re: Get a string of a function name from a function pointer?

2017-07-10 Thread Ali Çehreli via Digitalmars-d-learn

On 07/10/2017 05:26 AM, SauceKode wrote:
> I need to pass a group of (C) function pointers to another language from
> D... is there a way to derrive a name from a function pointer? Or do I
> have to manually list out the names?

libunwind should be able to provide that functionality. Otherwise, no, 
the function pointer itself does not contain any additional information.


Ali



Get a string of a function name from a function pointer?

2017-07-10 Thread SauceKode via Digitalmars-d-learn
I need to pass a group of (C) function pointers to another 
language from D... is there a way to derrive a name from a 
function pointer? Or do I have to manually list out the names?


Re: The reason for SIGSEGV function pointer problem

2017-06-08 Thread Russel Winder via Digitalmars-d-learn
Thanks also to Paolo Invernizzi and ag0aep6g for answering with a
similar response. Using Mike's response as it has extra detail.

On Wed, 2017-06-07 at 20:00 +0200, Mike Wey via Digitalmars-d-learn
wrote:
> On 06/07/2017 06:50 PM, Russel Winder via Digitalmars-d-learn wrote:
> > So why isn't  a thing of type check_frontend_t*
> 
> AFAIK, you would usually translate:
> 
> 
> typedef int (check_frontend_t*)(void *args, struct dvb_v5_fe_parms
> *parms);

The C code in dvb-scan.h is actually:

typedef int (check_frontend_t)(void *args, struct dvb_v5_fe_parms *parms);

> into:
> 
> alias check_frontend_t = extern(C) int function (void* args, 
> dvb_v5_fe_parms* parms);

I can't remember what DStep produced initially, but the above is what I
have in dvb_scan.d. Per se it seems consistent, but then functions in
D, and their signatures, may be totally different to functions in C.

> The problem there is that libdvdv5 defines it as (check_frontend_t)
> and 
> not (check_frontend_t*).
> To get around that you can ommit the * in the declaration of 
> dvb_scan_transponder, and then you should be able to pass
>  
> to it.

I am now at the stage of wondering if I remember C semantics, C++
semantics, and D semantics for "pointers to functions".

There may also be an issue of there being a bug in DStep…

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

signature.asc
Description: This is a digitally signed message part


Re: The reason for SIGSEGV function pointer problem

2017-06-07 Thread Mike Wey via Digitalmars-d-learn

On 06/07/2017 06:50 PM, Russel Winder via Digitalmars-d-learn wrote:

So why isn't  a thing of type check_frontend_t*


AFAIK, you would usually translate:


typedef int (check_frontend_t*)(void *args, struct dvb_v5_fe_parms *parms);

into:

alias check_frontend_t = extern(C) int function (void* args, 
dvb_v5_fe_parms* parms);


The problem there is that libdvdv5 defines it as (check_frontend_t) and 
not (check_frontend_t*).
To get around that you can ommit the * in the declaration of 
dvb_scan_transponder, and then you should be able to pass  
to it.


--
Mike Wey


Re: The reason for SIGSEGV function pointer problem

2017-06-07 Thread ag0aep6g via Digitalmars-d-learn

On 06/07/2017 06:50 PM, Russel Winder via Digitalmars-d-learn wrote:

So why isn't  a thing of type check_frontend_t*?


It's a thing of type `check_frontend_t`, which is a function pointer 
already. When you add an asterisk, you get a pointer to a function pointer.


Re: The reason for SIGSEGV function pointer problem

2017-06-07 Thread Paolo Invernizzi via Digitalmars-d-learn

On Wednesday, 7 June 2017 at 16:50:26 UTC, Russel Winder wrote:

In the constructor of an object to abstract the result of a 
call to the C library code, the parameter is:


check_frontend_t* cf



You should remove the pointer here...

/Paolo


The reason for SIGSEGV function pointer problem

2017-06-07 Thread Russel Winder via Digitalmars-d-learn
OK, so I have narrowed down my SIGSEGV problem to having no real idea
how to do C function pointers in D code.

So I have a callback function that will be called from C library code.
It currently has signature:

extern(C) int checkFrontend(void* _arguments, dvb_v5_fe_parms* 
frontendParameters)
 
because of the extern(C) I believe you have to use a type alias in
order to specify the type in function definitions. Hence:

alias check_frontend_t = extern(C) int function (void* args, 
dvb_v5_fe_parms* parms);

In the constructor of an object to abstract the result of a call to the
C library code, the parameter is:

check_frontend_t* cf

in the creation of the object using the constructor, I am using the
argument:



However. This gives me a type error:

extern (C) int function(void*, dvb_v5_fe_parms*)* cf

is not callable using argument type:

extern (C) int function(void*, dvb_v5_fe_parms*)

all the other arguments/parameters types match exactly, this is the
only difference.

So why isn't  a thing of type check_frontend_t*?

-- 
Russel.
=
Dr Russel Winder  t: +44 20 7585 2200   voip: sip:russel.win...@ekiga.net
41 Buckmaster Roadm: +44 7770 465 077   xmpp: rus...@winder.org.uk
London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder


Re: How to overload member function pointer and a regualr member function

2017-04-26 Thread ParticlePeter via Digitalmars-d-learn

On Wednesday, 26 April 2017 at 08:24:08 UTC, Basile B. wrote:

On Tuesday, 25 April 2017 at 18:58:58 UTC, Ali Çehreli wrote:

On 04/25/2017 11:54 AM, Ali Çehreli wrote:
My analysis is wrong because that writefln() is for the 
bar(float) overload but I still think what you want is 
achieved.


Ali


No it's ok, it works. The additional indirection is well 
avoided:


Let's take this module:

==
#!dmd -release -inline -O
module runnable;

struct Foo
{
private void function(int,float) _bar;
void bar(float){}
pragma(inline, false) void bar(int i, float f){_bar(i,f);}
}

struct FooInline
{
private void function(int,float) _bar;
void bar(float){}
pragma(inline, true) void bar(int i, float f){_bar(i,f);}
}

void testInlined(ref FooInline foo)
{
foo.bar(0,0);
}

void test(ref Foo foo)
{
foo.bar(0,0);
}

void main()
{
import disassembler, std.stdio;
disassembler.symbolTable.addModule!runnable;
prettyDisasm().writeln;
prettyDisasm(, 2).writeln; // dig up to 2 levels, 
required for the indir.

}
==

and looks at the output:


;--- SUB 00459970h ---
; NAMED: testInlined
00459970h  push rbp
00459971h  mov rbp, rsp
00459974h  sub rsp, 20h
00459978h  mov qword ptr [rbp-08h], rdi
0045997Ch  xor edi, edi
0045997Eh  mov dword ptr [rbp-20h], edi
00459981h  movss xmm0, dword ptr [rbp-20h]
00459986h  mov rax, qword ptr [rbp-08h]
0045998Ah  call qword ptr [rax]
0045998Dh  mov rsp, rbp
00459990h  pop rbp
00459991h  ret
;-


;--- SUB 00459934h ---
; XREFS: [004599A6h]
00459934h  push rbp
00459935h  mov rbp, rsp
00459938h  sub rsp, 10h
0045993Ch  mov qword ptr [rbp-08h], rdi
00459940h  mov rdi, rsi
00459943h  mov rax, qword ptr [rbp-08h]
00459947h  call qword ptr [rax]
0045994Ah  mov rsp, rbp
0045994Dh  pop rbp
0045994Eh  ret
;-

;--- SUB 00459994h ---
; NAMED: test
00459994h  push rbp
00459995h  mov rbp, rsp
00459998h  sub rsp, 10h
0045999Ch  xor esi, esi
0045999Eh  mov dword ptr [rbp-10h], esi
004599A1h  movss xmm0, dword ptr [rbp-10h]
004599A6h  call 00459934h
004599ABh  mov rsp, rbp
004599AEh  pop rbp
004599AFh  ret
;-

 - testInlined() contains only the delegate call. (call qword 
ptr [rax])
 - test() contains a call (call 00459934h) which 
contains the

   delegate call (call qword ptr [rax])

Actually i've even had to add (pragma inline false) to show the 
difference since DMD inlined automatically bar() in test().


Guys, you're great! Thanks a lot!


Re: How to overload member function pointer and a regualr member function

2017-04-26 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 25 April 2017 at 18:58:58 UTC, Ali Çehreli wrote:

On 04/25/2017 11:54 AM, Ali Çehreli wrote:
My analysis is wrong because that writefln() is for the 
bar(float) overload but I still think what you want is achieved.


Ali


No it's ok, it works. The additional indirection is well avoided:

Let's take this module:

==
#!dmd -release -inline -O
module runnable;

struct Foo
{
private void function(int,float) _bar;
void bar(float){}
pragma(inline, false) void bar(int i, float f){_bar(i,f);}
}

struct FooInline
{
private void function(int,float) _bar;
void bar(float){}
pragma(inline, true) void bar(int i, float f){_bar(i,f);}
}

void testInlined(ref FooInline foo)
{
foo.bar(0,0);
}

void test(ref Foo foo)
{
foo.bar(0,0);
}

void main()
{
import disassembler, std.stdio;
disassembler.symbolTable.addModule!runnable;
prettyDisasm().writeln;
prettyDisasm(, 2).writeln; // dig up to 2 levels, 
required for the indir.

}
==

and looks at the output:


;--- SUB 00459970h ---
; NAMED: testInlined
00459970h  push rbp
00459971h  mov rbp, rsp
00459974h  sub rsp, 20h
00459978h  mov qword ptr [rbp-08h], rdi
0045997Ch  xor edi, edi
0045997Eh  mov dword ptr [rbp-20h], edi
00459981h  movss xmm0, dword ptr [rbp-20h]
00459986h  mov rax, qword ptr [rbp-08h]
0045998Ah  call qword ptr [rax]
0045998Dh  mov rsp, rbp
00459990h  pop rbp
00459991h  ret
;-


;--- SUB 00459934h ---
; XREFS: [004599A6h]
00459934h  push rbp
00459935h  mov rbp, rsp
00459938h  sub rsp, 10h
0045993Ch  mov qword ptr [rbp-08h], rdi
00459940h  mov rdi, rsi
00459943h  mov rax, qword ptr [rbp-08h]
00459947h  call qword ptr [rax]
0045994Ah  mov rsp, rbp
0045994Dh  pop rbp
0045994Eh  ret
;-

;--- SUB 00459994h ---
; NAMED: test
00459994h  push rbp
00459995h  mov rbp, rsp
00459998h  sub rsp, 10h
0045999Ch  xor esi, esi
0045999Eh  mov dword ptr [rbp-10h], esi
004599A1h  movss xmm0, dword ptr [rbp-10h]
004599A6h  call 00459934h
004599ABh  mov rsp, rbp
004599AEh  pop rbp
004599AFh  ret
;-

 - testInlined() contains only the delegate call. (call qword ptr 
[rax])
 - test() contains a call (call 00459934h) which contains 
the

   delegate call (call qword ptr [rax])

Actually i've even had to add (pragma inline false) to show the 
difference since DMD inlined automatically bar() in test().







Re: How to overload member function pointer and a regualr member function

2017-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 04/25/2017 11:54 AM, Ali Çehreli wrote:

> _Dmain:
> pushRBP
> movRBP,RSP
> subRSP,010h
> movRAX,_D6deneme4funcFifZv@GOTPCREL[RIP]
> mov-010h[RBP],RAX
> movssXMM0,FLAT:.rodata[00h][RIP]
> movss-8[RBP],XMM0
> leaRDX,_TMP0@PC32[RIP]
> movEDI,0Eh
> movRSI,RDX
> movssXMM0,-8[RBP]
> call  _D3std5stdio17__T8writeflnTaTfZ8writeflnFNfxAafZv@PLT32
> movEAX,02Ah
> movssXMM1,FLAT:.rodata[00h][RIP]
> movss-4[RBP],XMM1
> movRDI,RAX
> movssXMM0,-4[RBP]
> callqword ptr -010h[RBP]
> xorEAX,EAX
> leave
> ret
> add[RAX],AL
> .text._Dmainends
>
> The call to jumbled writefln() is a direct call inside func():
>
> call  _D3std5stdio17__T8writeflnTaTfZ8writeflnFNfxAafZv@PLT32

My analysis is wrong because that writefln() is for the bar(float) 
overload but I still think what you want is achieved.


Ali



Re: How to overload member function pointer and a regualr member function

2017-04-25 Thread Ali Çehreli via Digitalmars-d-learn

On 04/25/2017 11:28 AM, ParticlePeter wrote:
> On Tuesday, 25 April 2017 at 16:27:43 UTC, Basile B. wrote:

>> with pragma(inline, true), the function body should be injected at the
>> call sites.
>
> This would not help I fear, the body of the function pointer is unknown
> in an external lib. I rather hoped that the compiler "sees" the
> parameter forwarding to the fp and is able to directly call it. Best
> thing would be for both overloads, but I would not know how to verify 
this.


pragma(inline, true) works because all you need inlined in this case is 
the body of bar(int, float). The compiler does call the function pointer 
directly.


import std.stdio;

struct Foo1
{
private void function(int,float) _bar;
void bar(float f) {
pragma(inline, true);
writefln("Called with %s", f);
}
void bar(int i, float f) {
pragma(inline, true);
_bar(i,f);
}
}

void func(int i, float f) {
writefln("Called with %s and %s", i, f);
}

void main() {
auto f = Foo1();
f.bar(1.5);
f.bar(42, 2.5);
}

Compile with -inline (and perhaps with -O):

  dmd -inline deneme.d

Generate the disassembly with obj2asm that comes with dmd (or with any 
other disassembly tool):


  obj2asm deneme.o > deneme.asm

You can open deneme.asm in an editor and search for function "_Dmain:" 
in it. Here is what my dmd 2.074 produced:


_Dmain:
pushRBP
mov RBP,RSP
sub RSP,010h
mov RAX,_D6deneme4funcFifZv@GOTPCREL[RIP]
mov -010h[RBP],RAX
movss   XMM0,FLAT:.rodata[00h][RIP]
movss   -8[RBP],XMM0
lea RDX,_TMP0@PC32[RIP]
mov EDI,0Eh
mov RSI,RDX
movss   XMM0,-8[RBP]
call  
_D3std5stdio17__T8writeflnTaTfZ8writeflnFNfxAafZv@PLT32
mov EAX,02Ah
movss   XMM1,FLAT:.rodata[00h][RIP]
movss   -4[RBP],XMM1
mov RDI,RAX
movss   XMM0,-4[RBP]
callqword ptr -010h[RBP]
xor EAX,EAX
leave
ret
add [RAX],AL
.text._Dmainends

The call to jumbled writefln() is a direct call inside func():

call  
_D3std5stdio17__T8writeflnTaTfZ8writeflnFNfxAafZv@PLT32

So, you're good... :)

Ali



Re: How to overload member function pointer and a regualr member function

2017-04-25 Thread ParticlePeter via Digitalmars-d-learn

On Tuesday, 25 April 2017 at 16:27:43 UTC, Basile B. wrote:

On Tuesday, 25 April 2017 at 15:43:48 UTC, ParticlePeter wrote:

On Tuesday, 25 April 2017 at 09:50:14 UTC, Basile B. wrote:

On Monday, 24 April 2017 at 16:46:21 UTC, ParticlePeter wrote:


Thanks for your reply, but that's what I would like to avoid, 
the additional indirection to call the function pointer with 
the original argument count.


Oops, i can believe i didn't read the last part of your 
question.


Do you have any idea about the likelihood of the compiler 
removing this indirection as an optimizations?


with pragma(inline, true), the function body should be injected 
at the call sites.


This would not help I fear, the body of the function pointer is 
unknown in an external lib. I rather hoped that the compiler 
"sees" the parameter forwarding to the fp and is able to directly 
call it. Best thing would be for both overloads, but I would not 
know how to verify this.


Re: How to overload member function pointer and a regualr member function

2017-04-25 Thread ParticlePeter via Digitalmars-d-learn

On Tuesday, 25 April 2017 at 09:50:14 UTC, Basile B. wrote:

On Monday, 24 April 2017 at 16:46:21 UTC, ParticlePeter wrote:

I would like to have this kind of struct:

struct Foo {
  private int i;
  void function( int i, float f ) bar;  // will be defined at 
runtime

  void bar( float f ) {
bar( i, f );
  }
}

[...]
How else can I get the required behavior?


Like this:

struct Foo1
{
private void function(int,float) _bar;
void bar(float){}
void bar(int i, float f){_bar(i,f);}
}


Thanks for your reply, but that's what I would like to avoid, the 
additional indirection to call the function pointer with the 
original argument count.
Do you have any idea about the likelihood of the compiler 
removing this indirection as an optimizations?


Re: How to overload member function pointer and a regualr member function

2017-04-25 Thread Basile B. via Digitalmars-d-learn

On Monday, 24 April 2017 at 16:46:21 UTC, ParticlePeter wrote:

I would like to have this kind of struct:

struct Foo {
  private int i;
  void function( int i, float f ) bar;  // will be defined at 
runtime

  void bar( float f ) {
bar( i, f );
  }
}

[...]
How else can I get the required behavior?


Like this:

struct Foo1
{
private void function(int,float) _bar;
void bar(float){}
void bar(int i, float f){_bar(i,f);}
}

Or like this:

struct Foo2
{
private void function(int,float) _bar;
void bar(float) {}
void function(int,float) bar() {return _bar;}
}


First solution looks better:

(new Foo2).bar()(0,0f) // less good
(new Foo1).bar(0,0f) // better




How to overload member function pointer and a regualr member function

2017-04-24 Thread ParticlePeter via Digitalmars-d-learn

I would like to have this kind of struct:

struct Foo {
  private int i;
  void function( int i, float f ) bar;  // will be defined at 
runtime

  void bar( float f ) {
bar( i, f );
  }
}

But apparently the function pointer and the member function 
cannot have the same name: Error: function main.Foo.bar conflicts 
with variable main.Foo.bar ...


I tried with an inner struct:
struct Foo {
  private int i;
  void function( int i, float f ) bar;  // will be defined at 
runtime

  private struct Inner {
void bar( float f ) {
  bar( i, f );
}
  }
  Inner inner;
}

But this time I get following error:
Error: need 'this' for 'i' of type 'int'

What does this message tell me? Should the inner struct not be 
able to access Foo.i?


How else can I get the required behavior?

I would prefer to avoid another indirection like this:
struct Foo {
  private int i;
  void function( int i, float f ) bar;  // will be defined at 
runtime

  void baz( float f ) {
bar( i, f );
  }
  void baz( int ii, float f ) {
bar( ii, f );
  }
}



Re: Function pointer pitfalls

2017-03-14 Thread Inquie via Digitalmars-d-learn

On Tuesday, 14 March 2017 at 19:14:34 UTC, H. S. Teoh wrote:
On Tue, Mar 14, 2017 at 06:59:58PM +, Inquie via 
Digitalmars-d-learn wrote:

[...]

[...]

> [...]

[...]

[...]

[...]

Keep in mind, though, that the above creates a function pointer 
with the same signature as the member function, but you may not 
be able to assign a member pointer to it because it lacks 
object context.  To wit:


[...]


Yeah, I don't think I'll run in to that problem since I'm 
constructing the function ahead of time and only need the 
declaration but we'll see.


Thanks again.




Re: Function pointer pitfalls

2017-03-14 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Mar 14, 2017 at 06:59:58PM +, Inquie via Digitalmars-d-learn wrote:
> On Tuesday, 14 March 2017 at 17:42:34 UTC, H. S. Teoh wrote:
[...]
> > struct X {
> > int method(float x) { return 0; }
> > }
> > 
> > typeof() membptr;
> > pragma(msg, typeof(membptr)); // prints `int function(float x)`
> > 
> > If you need to refer to the function pointer type frequently, you
> > could alias it to something easier to type;
> > 
> > alias FuncPtr = typeof();
> > FuncPtr membptr;
[...]
> Thanks, that will work. In C++ there were issues with pointers and one
> would have to properly group the function name or some thing like
> that. Your suggestion avoids all that.
[...]

Keep in mind, though, that the above creates a function pointer with the
same signature as the member function, but you may not be able to assign
a member pointer to it because it lacks object context.  To wit:


struct X {
int method(float x) { return 0; }
}

X x;

alias FuncPtr = typeof();
FuncPtr fp;

alias MembPtr = typeof();
MembPtr mp;

mp =  // OK
//fp =  // NG: cannot implicitly convert expression 
() of type int delegate(float z) to int function(float z)
-

 is a delegate because it encapsulates the instance of X that
it should be invoked with, so you can't assign it to a func ptr without
that context (since method() can't be called without an instance of X).


T

-- 
Question authority. Don't ask why, just do it.


Re: Function pointer pitfalls

2017-03-14 Thread Inquie via Digitalmars-d-learn

On Tuesday, 14 March 2017 at 17:42:34 UTC, H. S. Teoh wrote:
On Tue, Mar 14, 2017 at 05:05:10PM +, Inquie via 
Digitalmars-d-learn wrote:
I am generating member function pointers using the declaration 
specified from a standard member function. The standard member 
function is a valid D function that could use any types.


Is there any pitfalls like there are in C++ from generating a 
function pointer from them?


e.g.,

X foo(A,B,C) @R @S @T -> X function(A,B,C) @R @S @T fooptr;

In my case, there are no attributes, so that might ease the 
burden.


e.g., a template that converts a member function declaration.

ToFunctionPtr!("X foo(A,B,C) @R @S @T)", fooptr)

or

ToFunctionPtr!(foo, fooptr)

gives function pointer declaration who's declaration is the 
same as foo.


Not 100% sure what exactly you mean... but I'm guessing you 
have some aggregate X with some member function method(), and 
you want to get a function pointer from that? Perhaps something 
like this?


struct X {
int method(float x) { return 0; }
}

typeof() membptr;
pragma(msg, typeof(membptr)); // prints `int function(float x)`

If you need to refer to the function pointer type frequently, 
you could alias it to something easier to type;


alias FuncPtr = typeof();
FuncPtr membptr;


T


Thanks, that will work. In C++ there were issues with pointers 
and one would have to properly group the function name or some 
thing like that. Your suggestion avoids all that.





Re: Function pointer pitfalls

2017-03-14 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Mar 14, 2017 at 05:05:10PM +, Inquie via Digitalmars-d-learn wrote:
> I am generating member function pointers using the declaration
> specified from a standard member function. The standard member
> function is a valid D function that could use any types.
> 
> Is there any pitfalls like there are in C++ from generating a function
> pointer from them?
> 
> e.g.,
> 
> X foo(A,B,C) @R @S @T -> X function(A,B,C) @R @S @T fooptr;
> 
> In my case, there are no attributes, so that might ease the burden.
> 
> e.g., a template that converts a member function declaration.
> 
> ToFunctionPtr!("X foo(A,B,C) @R @S @T)", fooptr)
> 
> or
> 
> ToFunctionPtr!(foo, fooptr)
> 
> gives function pointer declaration who's declaration is the same as
> foo.

Not 100% sure what exactly you mean... but I'm guessing you have some
aggregate X with some member function method(), and you want to get a
function pointer from that? Perhaps something like this?

struct X {
int method(float x) { return 0; }
}

typeof() membptr;
pragma(msg, typeof(membptr)); // prints `int function(float x)`

If you need to refer to the function pointer type frequently, you could
alias it to something easier to type;

alias FuncPtr = typeof();
FuncPtr membptr;


T

-- 
Turning your clock 15 minutes ahead won't cure lateness---you're just making 
time go faster!


Function pointer pitfalls

2017-03-14 Thread Inquie via Digitalmars-d-learn
I am generating member function pointers using the declaration 
specified from a standard member function. The standard member 
function is a valid D function that could use any types.


Is there any pitfalls like there are in C++ from generating a 
function pointer from them?


e.g.,

X foo(A,B,C) @R @S @T -> X function(A,B,C) @R @S @T fooptr;

In my case, there are no attributes, so that might ease the 
burden.


e.g., a template that converts a member function declaration.

ToFunctionPtr!("X foo(A,B,C) @R @S @T)", fooptr)

or

ToFunctionPtr!(foo, fooptr)

gives function pointer declaration who's declaration is the same 
as foo.




Re: How can I implement this in D: a variant array of varying function pointer types (diff number of args or types)

2017-01-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 17 January 2017 at 10:49:14 UTC, Enjoys Math wrote:

Z add(Z...)(Z a...) {
return a + b;
}

func[] operatorPool = [!int];

Variant library isn't liking that.  Removing & causes another 
error.


Essentially I want a pool of all operators that I define, but 
these operators can be of differing types (which I should be 
able to programatically grab), and different N-aryness.


Try using `variantArray` from std.variant. see 
https://dlang.org/phobos/std_variant.html#.variantArray


Re: How can I implement this in D: a variant array of varying function pointer types (diff number of args or types)

2017-01-17 Thread Enjoys Math via Digitalmars-d-learn

On Tuesday, 17 January 2017 at 10:49:14 UTC, Enjoys Math wrote:

Z add(Z...)(Z a...) {
return a + b;
}

func[] operatorPool = [!int];

Variant library isn't liking that.  Removing & causes another 
error.


Essentially I want a pool of all operators that I define, but 
these operators can be of differing types (which I should be 
able to programatically grab), and different N-aryness.


func?  I mean std.variant.Variant there.


How can I implement this in D: a variant array of varying function pointer types (diff number of args or types)

2017-01-17 Thread Enjoys Math via Digitalmars-d-learn

Z add(Z...)(Z a...) {
return a + b;
}

func[] operatorPool = [!int];

Variant library isn't liking that.  Removing & causes another 
error.


Essentially I want a pool of all operators that I define, but 
these operators can be of differing types (which I should be able 
to programatically grab), and different N-aryness.





Re: Cryptic C function pointer for conversion

2016-12-17 Thread bachmeier via Digitalmars-d-learn
On Saturday, 17 December 2016 at 15:15:26 UTC, data pulverizer 
wrote:


Does this mean that you can translate C code to D natively? I 
am currently only aware of the dstep package.


It may not help you, but something I've done in the past is use 
Swig to create a Common Lisp interface. It translates the C to 
Common Lisp. That is generally much easier for me to understand.


Re: Cryptic C function pointer for conversion

2016-12-17 Thread ketmar via Digitalmars-d-learn
p.s.: that means that i didn't really *decoded* that declaration, 
just brute-forced someting that c++ compiler happily accepts. so 
take it with a grain of salt. ;-)


Re: Cryptic C function pointer for conversion

2016-12-17 Thread data pulverizer via Digitalmars-d-learn

On Saturday, 17 December 2016 at 14:06:07 UTC, ketmar wrote:
On Saturday, 17 December 2016 at 13:39:27 UTC, data pulverizer 
wrote:


that is what it means, in D:

//void (*(*xDlSym)(sqlite3_vfs*,void*, const char 
*zSymbol))(void);


struct sqlite3_vfs {}

extern(C) {
alias RetRes = void function ();
alias DeclType = RetRes function (sqlite3_vfs *a,void *b, const 
char *zSymbol);


DeclType xDlSym;

void zoo (void) {}
auto goo (sqlite3_vfs *a,void *b, const char *zSymbol) { return 
 }

}

void main () {
  xDlSym = 
}


at least that is what i managed to decode, fed to C(++) 
compiler and translate to D.


p.s. I confirmed your interpretation on stackoverflow:

http://stackoverflow.com/questions/8722817/syntax-for-a-pointer-to-a-function-returning-a-function-pointer-in-c



Re: Cryptic C function pointer for conversion

2016-12-17 Thread ketmar via Digitalmars-d-learn
On Saturday, 17 December 2016 at 15:15:26 UTC, data pulverizer 
wrote:


Does this mean that you can translate C code to D natively? I 
am currently only aware of the dstep package.


with my head and bare hands. well, armed with some regular 
expressions. did you seen some of my "port" announcements? they 
all done manually. it's not that hard, mostly search-and-replace.


also, i did used c++ 'cause it has `auto` feature, so i pasted 
your declaration, and then played with c++ and -Wall until it 
silenced. actually,


void zoo (void) {}
auto goo (sqlite3_vfs *a,void *b, const char *zSymbol) { return 
 }


was taken verbatim from c++. as you can see, it even has 
`(void)`, which is forbidden in D (but allowed in my dmd fork ;-).


Re: Cryptic C function pointer for conversion

2016-12-17 Thread data pulverizer via Digitalmars-d-learn

On Saturday, 17 December 2016 at 14:06:07 UTC, ketmar wrote:

that is what it means, in D:

//void (*(*xDlSym)(sqlite3_vfs*,void*, const char 
*zSymbol))(void);


struct sqlite3_vfs {}

extern(C) {
alias RetRes = void function ();
alias DeclType = RetRes function (sqlite3_vfs *a,void *b, const 
char *zSymbol);

...
}


Thanks ketmar,

I guess that this means I got it the other way round the function 
pointer that is returned is the function that takes in and 
returns void.


at least that is what i managed to decode, fed to C(++) 
compiler and translate to D.


Does this mean that you can translate C code to D natively? I am 
currently only aware of the dstep package.





Re: Cryptic C function pointer for conversion

2016-12-17 Thread ketmar via Digitalmars-d-learn
On Saturday, 17 December 2016 at 13:39:27 UTC, data pulverizer 
wrote:


that is what it means, in D:

//void (*(*xDlSym)(sqlite3_vfs*,void*, const char 
*zSymbol))(void);


struct sqlite3_vfs {}

extern(C) {
alias RetRes = void function ();
alias DeclType = RetRes function (sqlite3_vfs *a,void *b, const 
char *zSymbol);


DeclType xDlSym;

void zoo (void) {}
auto goo (sqlite3_vfs *a,void *b, const char *zSymbol) { return 
 }

}

void main () {
  xDlSym = 
}


at least that is what i managed to decode, fed to C(++) compiler 
and translate to D.


Cryptic C function pointer for conversion

2016-12-17 Thread data pulverizer via Digitalmars-d-learn
I have come across a function pointer in C that I am attempting 
to convert, and am not sure what the current interpretation is:


```
\\ The C Code:
void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);
```

The best I can tell is that this is a function pointer that 
returns a function that returns void and the correct translation 
to D is:


```
alias void function(sqlite3_vfs*,void*, const char *zSymbol) ptr;
ptr* function() xDlSym;
```

I've never seen a construction like this before so my 
interpretation might be wrong!


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread jmh530 via Digitalmars-d-learn

On Friday, 19 February 2016 at 22:34:48 UTC, Chris Wright wrote:


I tested this a fair bit today, and I haven't been able to do 
any of the nefarious things I expected to be able to do. No 
overwriting variables in the caller's scope, no smashing stack 
pointers, etc.


I was surprised by this result, but in retrospect, it's 
relatively obvious. The caller pushes variables onto the stack 
and sets the stack pointer for the callee. It wouldn't send a 
stack pointer that pointed into its own stack frame.


Thanks for taking the time to test.

The more I've thought about it, the more I wonder if there should 
be a restriction so that casts of function pointers/delegate 
maintain the same number of parameters. Even though you haven't 
been able to do nefarious things, it's giving a completely wrong 
answer than you would expect. The result of the answer might 
cause bad things to happen in a program. Further, to even 
understand what's going wrong you have to understand how the 
compiler is generating assembly. I've been using D for like a 
year or so, and I would never have been able to figure out the 
reason by myself.


Or at least in safe code you shouldn't be able to do this.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Chris Wright via Digitalmars-d-learn
On Fri, 19 Feb 2016 21:57:46 +, Yuxuan Shui wrote:

> I don't think it's safe to convert between function pointer with
> different number of arguments... It's possible to mess up the stack
> frame.

I tested this a fair bit today, and I haven't been able to do any of the 
nefarious things I expected to be able to do. No overwriting variables in 
the caller's scope, no smashing stack pointers, etc.

I was surprised by this result, but in retrospect, it's relatively 
obvious. The caller pushes variables onto the stack and sets the stack 
pointer for the callee. It wouldn't send a stack pointer that pointed 
into its own stack frame.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread jmh530 via Digitalmars-d-learn

On Friday, 19 February 2016 at 22:07:25 UTC, Chris Wright wrote:


If you want to cast function pointers successfully, you have to 
know the D calling convention.


[snip]


I figured there was an explanation. Definitely "here be dragons" 
territory. I hope I can figure out a better solution, but the 
behavior I'm trying to get is really just a nice to have.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Chris Wright via Digitalmars-d-learn
On Fri, 19 Feb 2016 20:45:23 +, jmh530 wrote:

> I tried to use a cast (below) to modify the function pointer, but it is
> printing the second number instead of the first. I find this behavior
> strange...

If you want to cast function pointers successfully, you have to know the 
D calling convention.

See: https://dlang.org/spec/abi.html

Notably: "The last parameter is passed in EAX [a CPU register] rather 
than being pushed on the stack". So foo expected an argument in EAX, and 
it dealt with that. Calling foo_ pushes '1' onto the stack, sets EAX to 
'200', and then jumps to the function address.

(But note also: "The callee cleans the stack." So if you pass, say, a 
struct that has a destructor instead of an integer, that means the struct 
destructor won't be called. I was a little surprised that the stack 
pointer is correctly restored.)

If you had more arguments, you'd find similar results -- the last 
argument always goes to EAX, previous arguments are pushed on the stack 
in order, so you're always ignoring a prefix of the arguments. But it's a 
byte-wise prefix, so if you change the types, you'll see more significant 
changes.

Casting function pointers is "here be dragons" territory. Unfortunately, 
it's got the same syntax as routine stuff like integer truncation and 
class casts, so it looks deceptively safe.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Yuxuan Shui via Digitalmars-d-learn

On Friday, 19 February 2016 at 20:45:23 UTC, jmh530 wrote:

On Friday, 19 February 2016 at 15:00:51 UTC, jmh530 wrote:


This works.

But when I re-write foo to take that into account as in below, 
I get an error that I can't implicitly convert int 
function(int x) to int function(int x, int y).



I don't think I had looked at what you had done carefully 
enough. Basically, you just define a new function and take a 
function pointer of that. That might be a brute force solution.


I tried to use a cast (below) to modify the function pointer, 
but it is printing the second number instead of the first. I 
find this behavior strange...


int foo(int x)
{
return x;
}

void main()
{
import std.stdio : writeln;

auto foo_ = cast(int function(int x, int y)) 

writeln(foo_(1, 200)); //prints 200
}


I don't think it's safe to convert between function pointer with 
different number of arguments... It's possible to mess up the 
stack frame.


Also '(int x, int y)=>f(x)' is clearly a delegate because it 
refers to local variable 'f', you can't just cast it to 'int 
function(int, int)'.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread jmh530 via Digitalmars-d-learn

On Friday, 19 February 2016 at 15:00:51 UTC, jmh530 wrote:


This works.

But when I re-write foo to take that into account as in below, 
I get an error that I can't implicitly convert int function(int 
x) to int function(int x, int y).



I don't think I had looked at what you had done carefully enough. 
Basically, you just define a new function and take a function 
pointer of that. That might be a brute force solution.


I tried to use a cast (below) to modify the function pointer, but 
it is printing the second number instead of the first. I find 
this behavior strange...


int foo(int x)
{
return x;
}

void main()
{
import std.stdio : writeln;

auto foo_ = cast(int function(int x, int y)) 

writeln(foo_(1, 200)); //prints 200
}


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread jmh530 via Digitalmars-d-learn

On Friday, 19 February 2016 at 14:21:26 UTC, Kagamin wrote:


int bar(int x)
{
return x;
}

int baz(int x, int y)
{
return bar(x);
}

void main()
{
import std.stdio : writeln;

int function(int x, int y) foo_bar = 

writeln(foo_bar(1, 2));
}


This works.

But when I re-write foo to take that into account as in below, I 
get an error that I can't implicitly convert int function(int x) 
to int function(int x, int y).


auto foo(T)(T f)
{
static if (is(T == fp2))
{
return f;
}
else static if (is(T == fp1))
{
int function(int x, int y) f_ = f;
return f_;
}
else
{
return 0;
}
}


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread jmh530 via Digitalmars-d-learn
On Friday, 19 February 2016 at 11:26:56 UTC, Nicholas Wilson 
wrote:


Like

alias fp1 = int function(int x);
alias fp2 = int function(int x, int y);

auto foo(T)(T f)
{
static if (is(T == fp2))
return f;
else static if (is(T == fp1))
{
return int function(int x, int y) => f(x);
}
else
return 0;
}


?


This code doesn't compile for me. I have to adjust it to

return function int(int x, int y) => f(x);

and then it complains that it's a delegate.


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Kagamin via Digitalmars-d-learn

On Friday, 19 February 2016 at 05:41:01 UTC, jmh530 wrote:

void main()
{
import std.stdio : writeln;

auto foo_bar = foo();

writeln(qux(1, 2, foo_bar)); //compiler error
writeln(qux(1, 2, ));
}


int bar(int x)
{
return x;
}

int baz(int x, int y)
{
return bar(x);
}

void main()
{
import std.stdio : writeln;

int function(int x, int y) foo_bar = 

writeln(foo_bar(1, 2));
}



Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 19 February 2016 at 05:41:01 UTC, jmh530 wrote:
I'm trying to write a function that will adjust the parameters 
of a function pointer.




I think the problem is that it defaults to a delegate not that it 
cannot be one

does clarifying this to the compiler work

Like

alias fp1 = int function(int x);
alias fp2 = int function(int x, int y);

auto foo(T)(T f)
{
static if (is(T == fp2))
return f;
else static if (is(T == fp1))
{
return int function(int x, int y) => f(x);
}
else
return 0;
}


?


Modify Function Pointer to Take Additional Parameters

2016-02-18 Thread jmh530 via Digitalmars-d-learn
I'm trying to write a function that will adjust the parameters of 
a function pointer.


In the code below, my goal is to call the function qux with a 
variety of different function pointers (in the actual 
application, I don't have the ability to modify qux). I created a 
function foo that I thought would adjust it properly. The problem 
is that the foo function converts the function pointer into a 
delegate.


I was able to get something that works in this simple example by 
introducing a delegate alias and an alternate definition of qux 
that takes a delegate. However, in my actual application, I can't 
modify what the equivalent of qux would take as parameters.


So I was just curious if there was any other alternative.


alias fp1 = int function(int x);
alias fp2 = int function(int x, int y);

auto foo(T)(T f)
{
static if (is(T == fp2))
return f;
else static if (is(T == fp1))
{
return (int x, int y) => f(x);
}
else
return 0;
}

int bar(int x)
{
return x;
}

int baz(int x, int y)
{
return x + y;
}

int qux(int x, int y, fp2 f)
{
return f(x, y);
}

void main()
{
import std.stdio : writeln;

auto foo_bar = foo();

writeln(qux(1, 2, foo_bar)); //compiler error
writeln(qux(1, 2, ));
}



Re: LNK2019 error from using a function pointer to core.bitop functions?

2015-07-17 Thread Roland Hadinger via Digitalmars-d-learn

On Friday, 17 July 2015 at 15:47:39 UTC, Roland Hadinger wrote:
Otherwise, I'd use templates and an alias. Maybe this will 
result in faster code:


bool opIndexAssign(bool value, size_t[2] inds)
{
void impl(bool b)(size_t[2] inds)
{
static if(b)
alias btx = bts;
else
alias btx = btr;

// code from opIndexAssign goes here...
// for (size_t i = startBitInd; ...
}

if( value )
impl!true(inds);
else
impl!false(inds);


  return value; // oops

}




Re: LNK2019 error from using a function pointer to core.bitop functions?

2015-07-17 Thread Roland Hadinger via Digitalmars-d-learn

On Thursday, 16 July 2015 at 03:24:54 UTC, Matthew Gamble wrote:
This member function of my struct uses a function pointer btx. 
When the line declaring the function pointer is present I get a 
LNK2019 error: unresolved external symbol.


Just guessing, probably because bts and btr are intrinsics?

If performance is not that important, you can always do this at 
the start of your opIndexAssign method:


static int bts(size_t* p, size_t bitnum) { return .bts(p, 
bitnum); }
static int btr(size_t* p, size_t bitnum) { return .btr(p, 
bitnum); }

int function(size_t*, size_t) btx = (value) ? bts : btr;

Otherwise, I'd use templates and an alias. Maybe this will result 
in faster code:


bool opIndexAssign(bool value, size_t[2] inds)
{
void impl(bool b)(size_t[2] inds)
{
static if(b)
alias btx = bts;
else
alias btx = btr;

// code from opIndexAssign goes here...
// for (size_t i = startBitInd; ...
}

if( value )
impl!true(inds);
else
impl!false(inds);
}



Re: LNK2019 error from using a function pointer to core.bitop functions?

2015-07-17 Thread Matthew Gamble via Digitalmars-d-learn

On Friday, 17 July 2015 at 15:49:46 UTC, Roland Hadinger wrote:

On Friday, 17 July 2015 at 15:47:39 UTC, Roland Hadinger wrote:
Otherwise, I'd use templates and an alias. Maybe this will 
result in faster code:


bool opIndexAssign(bool value, size_t[2] inds)
{
void impl(bool b)(size_t[2] inds)
{
static if(b)
alias btx = bts;
else
alias btx = btr;

// code from opIndexAssign goes here...
// for (size_t i = startBitInd; ...
}

if( value )
impl!true(inds);
else
impl!false(inds);


  return value; // oops

}


Roland, both of your solutions work perfectly. Thank you.

You brought up the issue of performance. Performance may be an 
issue for certain use-cases when the function is called many 
times and the values of inds[1] - inds[0] is small (e.g less than 
257). In these cases at least half the work in the function will 
be done with bts/btr. However, for larger ranges there is an 
optimization (not shown) that eliminates the need to call bts/btr 
in the middle region of the range.


Why do you think the second solution would be faster than the 
first? And do you also think that the rolled out version 
replicating the code in the if and else blocks replacing bts 
with btr would be even faster since it eliminates the need for 
any additional function call? I guess I'll have to profile all 
three versions when my program matures enough be used with a 
big data example.


Sorry for all the questions. I really appreciate your help.

Best, Matt


LNK2019 error from using a function pointer to core.bitop functions?

2015-07-15 Thread Matthew Gamble via Digitalmars-d-learn
This member function of my struct uses a function pointer btx. 
When the line declaring the function pointer is present I get a 
LNK2019 error: unresolved external symbol.


bool opIndexAssign(bool value, size_t[2] inds)
{
	int function(size_t*, size_t) btx = (value) ? bts : btr; // 
error is here


// other stuff here

	for (size_t i = startBitInd; i  startWordBitDone; ++i) 
btx(bitArray[startWord], i);


// other stuff here

	if (startWord != stopWord) for (size_t i = 0; i  stopBitInd; 
++i) btx(bitArray[stopWord], i);

return value;
}


However, when I don't use the function pointer and instead call 
bts directly (as outlined below, the program compiles and links 
just fine.


bool opIndexAssign(bool value, size_t[2] inds)
{

// other stuff here

	for (size_t i = startBitInd; i  startWordBitDone; ++i) 
bts(bitArray[startWord], i);


// other stuff here

	if (startWord != stopWord) for (size_t i = 0; i  stopBitInd; 
++i) bts(bitArray[stopWord], i);

return value;
}

Any ideas how to fix this behavior? I was trying to use the 
function pointer so I wouldn't need to write essentially the same 
code block replacing bts with btr in if and else blocks


Any help would be appreciated. Thanks


Re: Function pointer array slice?

2015-07-11 Thread ketmar via Digitalmars-d-learn
On Sat, 11 Jul 2015 09:54:40 +, tcak wrote:

 On Saturday, 11 July 2015 at 09:30:43 UTC, Tofu Ninja wrote:
 So simple syntax question, how do I make an array slice of function
 pointers?

 I just have no idea where to put the [] on something like

  void function() nothrow pure @nogc @safe arrayName;

 Or should I just alias it and make an array of the alias?

  alias f = void function() nothrow pure @nogc @safe;
  f[] arrayName;
 
 Alias is the correct way IMO.

yet

  void function() nothrow pure @nogc @safe [2]arrayName;

is perfectly fine too.

signature.asc
Description: PGP signature


Function pointer array slice?

2015-07-11 Thread Tofu Ninja via Digitalmars-d-learn
So simple syntax question, how do I make an array slice of 
function pointers?


I just have no idea where to put the [] on something like

 void function() nothrow pure @nogc @safe arrayName;

Or should I just alias it and make an array of the alias?

 alias f = void function() nothrow pure @nogc @safe;
 f[] arrayName;


Re: Function pointer array slice?

2015-07-11 Thread Tofu Ninja via Digitalmars-d-learn

On Saturday, 11 July 2015 at 10:54:45 UTC, ketmar wrote:

On Sat, 11 Jul 2015 09:54:40 +, tcak wrote:


On Saturday, 11 July 2015 at 09:30:43 UTC, Tofu Ninja wrote:
So simple syntax question, how do I make an array slice of 
function pointers?


I just have no idea where to put the [] on something like

 void function() nothrow pure @nogc @safe arrayName;

Or should I just alias it and make an array of the alias?

 alias f = void function() nothrow pure @nogc @safe;
 f[] arrayName;


Alias is the correct way IMO.


yet

  void function() nothrow pure @nogc @safe [2]arrayName;

is perfectly fine too.


Ahh, guess that makes sense, I kept trying to put the [] over 
near function()... looks weird as hell though. I really wish you 
could put types in parens, I feel like things like this would 
make way more sense if you could write


 (void function() nothrow pure @nogc @safe)[] arrayName;

Reading it, that makes wayyy more sense to me, to bad I can't 
write this...


Re: Function pointer array slice?

2015-07-11 Thread tcak via Digitalmars-d-learn

On Saturday, 11 July 2015 at 09:30:43 UTC, Tofu Ninja wrote:
So simple syntax question, how do I make an array slice of 
function pointers?


I just have no idea where to put the [] on something like

 void function() nothrow pure @nogc @safe arrayName;

Or should I just alias it and make an array of the alias?

 alias f = void function() nothrow pure @nogc @safe;
 f[] arrayName;


Alias is the correct way IMO.


Re: Function pointer array slice?

2015-07-11 Thread ketmar via Digitalmars-d-learn
On Sat, 11 Jul 2015 11:37:03 +, Tofu Ninja wrote:

   void function() nothrow pure @nogc @safe [2]arrayName;

 is perfectly fine too.
 
 Ahh, guess that makes sense, I kept trying to put the [] over near
 function()...

attributes are the parts of the type. and the rule is really simple: put 
[] array declaration immediately left of the array name. ;-)

 looks weird as hell though. I really wish you could put
 types in parens, I feel like things like this would make way more sense
 if you could write
 
   (void function() nothrow pure @nogc @safe)[] arrayName;
 
 Reading it, that makes wayyy more sense to me, to bad I can't write
 this...

i agree, this is somewhat easier to read. but it requires grammar 
changes, i believe, and dunno what consequences that may have. yet it may 
worth filling a ER.

signature.asc
Description: PGP signature


Re: Function name from function pointer

2015-04-11 Thread Paul D Anderson via Digitalmars-d-learn

On Saturday, 11 April 2015 at 19:08:50 UTC, Marco Leise wrote:

Am Sat, 11 Apr 2015 18:28:35 +
schrieb Paul D Anderson claude.re...@msnmail.com:

Is there a way to return the name of a function (a string) 
from a pointer to that function?


Function pointer example from D Reference:
---
int function() fp;

void test()
{
 static int a = 7;
 static int foo() { return a + 3; }

 fp = foo;
}

void bar()
{
 test();
 int i = fp();   // i is set to 10
}
---

Can I get foo from fp?

Paul




Nope, that would require that fp not only contains a pointer
to the function but also a pointer to the name. That's not how
it works. But continuing that thought, you could add the
function's name as an additional variable and set that every
time you set fp.


Okay, thanks, I can see that.

Paul


Re: Function name from function pointer

2015-04-11 Thread Marco Leise via Digitalmars-d-learn
Am Sat, 11 Apr 2015 18:28:35 +
schrieb Paul D Anderson claude.re...@msnmail.com:

 Is there a way to return the name of a function (a string) from a 
 pointer to that function?
 
 Function pointer example from D Reference:
 ---
 int function() fp;
 
 void test()
 {
  static int a = 7;
  static int foo() { return a + 3; }
 
  fp = foo;
 }
 
 void bar()
 {
  test();
  int i = fp();   // i is set to 10
 }
 ---
 
 Can I get foo from fp?
 
 Paul
 
 

Nope, that would require that fp not only contains a pointer
to the function but also a pointer to the name. That's not how
it works. But continuing that thought, you could add the
function's name as an additional variable and set that every
time you set fp.

-- 
Marco



Re: Function name from function pointer

2015-04-11 Thread bearophile via Digitalmars-d-learn

Paul D Anderson:

Is there a way to return the name of a function (a string) from 
a pointer to that function?


Perhaps creating a string[void*] AA and initializing with all the 
function pointers you care about.


Bye,
bearophile


Function name from function pointer

2015-04-11 Thread Paul D Anderson via Digitalmars-d-learn
Is there a way to return the name of a function (a string) from a 
pointer to that function?


Function pointer example from D Reference:
---
int function() fp;

void test()
{
static int a = 7;
static int foo() { return a + 3; }

fp = foo;
}

void bar()
{
test();
int i = fp();   // i is set to 10
}
---

Can I get foo from fp?

Paul




Re: Function pointer to member function.

2013-10-17 Thread TheFlyingFiddle

On Thursday, 17 October 2013 at 03:21:38 UTC, Chris Cain wrote:
On Thursday, 17 October 2013 at 01:17:21 UTC, TheFlyingFiddle 
wrote:

I would like to get access to a member function pointer. Taking
the this* as
the first argument.

...snip...
How should i implement getFP above? Is it even possible?


Well, it's certainly possible. If you were to do this:
```
delegate void(int) dg = a.bar;
dg(1);
```
then you'd see the behavior you're looking for. Basically the 
class reference is stored in dg.ptr and the function is in 
dg.funcptr.


With that in mind, I whipped this up:
```
import std.stdio;

class Foo {
char c;
this() {
c = 'a';
}
this(char _c) {
c = _c;
}
void bar(int i) {
writeln(i = , i,  c = , c);
}
}

import std.traits;
//ParentOf!S is pseudocode representing __traits(parent, S)
//ReturnType!S function(ParentOf!S, ParameterTypeTuple!S)
auto getFP(alias S)() if(isSomeFunction!S) {
mixin(alias Parent =  ~ __traits(parent, S).stringof ~ 
;);

return (Parent r, ParameterTypeTuple!S t) {
ReturnType!S delegate(ParameterTypeTuple!S) dg;
dg.funcptr = S;
dg.ptr = cast(void*) r;
return dg(t);
};
}

void main() {
Foo a = new Foo();
Foo b = new Foo('b');

auto fp = getFP!(Foo.bar);
fp(a, 1);
fp(b, 2);
}
```

Now one thing to note is that I'm not confident it's bug-free. 
It does work in this test case, but I couldn't use 
__traits(parent, S) as a type, so I used a mixin to kind of 
force it to work. So I'm not fully sure whether it will work in 
all cases, but if someone else has some improvements, that's 
fine.


Another thing: I didn't spend too much time on the template 
constraint. isSomeFunction is almost certainly too 
permissive. I just threw it together and I haven't coded in D 
for a while.


I hope this helped!


Thanks, this works well for my needs.


Function pointer to member function.

2013-10-16 Thread TheFlyingFiddle

I would like to get access to a member function pointer. Taking
the this* as
the first argument.

class Foo
{
void bar(int a)
{
   //do something awesome
}
}

unittest
{
Foo a = new Foo();
Foo b = new Foo();

auto fp = getFP!(Foo.bar);
fp(a, 1); //Basically calls a.foo(1)
fp(b, 1); //Basically calls b.foo(1)
}

How should i implement getFP above? Is it even possible?


Re: Function pointer to member function.

2013-10-16 Thread Chris Cain
On Thursday, 17 October 2013 at 01:17:21 UTC, TheFlyingFiddle 
wrote:

I would like to get access to a member function pointer. Taking
the this* as
the first argument.

...snip...
How should i implement getFP above? Is it even possible?


Well, it's certainly possible. If you were to do this:
```
delegate void(int) dg = a.bar;
dg(1);
```
then you'd see the behavior you're looking for. Basically the 
class reference is stored in dg.ptr and the function is in 
dg.funcptr.


With that in mind, I whipped this up:
```
import std.stdio;

class Foo {
char c;
this() {
c = 'a';
}
this(char _c) {
c = _c;
}
void bar(int i) {
writeln(i = , i,  c = , c);
}
}

import std.traits;
//ParentOf!S is pseudocode representing __traits(parent, S)
//ReturnType!S function(ParentOf!S, ParameterTypeTuple!S)
auto getFP(alias S)() if(isSomeFunction!S) {
mixin(alias Parent =  ~ __traits(parent, S).stringof ~ ;);
return (Parent r, ParameterTypeTuple!S t) {
ReturnType!S delegate(ParameterTypeTuple!S) dg;
dg.funcptr = S;
dg.ptr = cast(void*) r;
return dg(t);
};
}

void main() {
Foo a = new Foo();
Foo b = new Foo('b');

auto fp = getFP!(Foo.bar);
fp(a, 1);
fp(b, 2);
}
```

Now one thing to note is that I'm not confident it's bug-free. It 
does work in this test case, but I couldn't use __traits(parent, 
S) as a type, so I used a mixin to kind of force it to work. So 
I'm not fully sure whether it will work in all cases, but if 
someone else has some improvements, that's fine.


Another thing: I didn't spend too much time on the template 
constraint. isSomeFunction is almost certainly too permissive. 
I just threw it together and I haven't coded in D for a while.


I hope this helped!


Re: Call a function with a function pointer

2013-10-13 Thread Benjamin Thaut

Am 10.10.2013 17:45, schrieb Namespace:

On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:

Namespace:


You mean like this?

void foo(T)(extern(C) void function(T*) func) {

}


That prints: Error: basic type expected, not extern


In theory that's correct, in practice the compiler refuses that, it's
in Bugzilla, so try to define the type outside the signature (untested):

alias TF = extern(C) void function(T*);

void foo(T)(TF func) {}

Bye,
bearophile


/d917/f732.d(8): Error: basic type expected, not extern
/d917/f732.d(8): Error: semicolon expected to close alias declaration
/d917/f732.d(8): Error: no identifier for declarator void function(T*)


I found a possible workaround. Its ugly as hell, but at least it works 
until the bugs are fixed. The trick is to make a helper struct. Define 
the function you want within that, and then use typeof to get the type.



import std.stdio;

extern(C) void testFunc(int* ptr)
{
*ptr = 5;
}

struct TypeHelper(T)
{
extern(C) static void func(T*);
alias typeof(func) func_t;
}

void Foo(T)(TypeHelper!T.func_t func, T* val)
{
func(val);
}

void main(string[] args)
{
pragma(msg, TypeHelper!int.func_t.stringof);
int test = 0;
Foo!int(testFunc, test);
writefln(%d, test);
}

--
Kind Regards
Benjamin Thaut


Re: Call a function with a function pointer

2013-10-13 Thread Artur Skawina
On 10/13/13 16:43, Benjamin Thaut wrote:
 Am 10.10.2013 17:45, schrieb Namespace:
 On Thursday, 10 October 2013 at 15:15:45 UTC, bearophile wrote:
 Namespace:

 You mean like this?
 
 void foo(T)(extern(C) void function(T*) func) {

 }
 

 That prints: Error: basic type expected, not extern

 In theory that's correct, in practice the compiler refuses that, it's
 in Bugzilla, so try to define the type outside the signature (untested):

 alias TF = extern(C) void function(T*);

 void foo(T)(TF func) {}

 Bye,
 bearophile

 /d917/f732.d(8): Error: basic type expected, not extern
 /d917/f732.d(8): Error: semicolon expected to close alias declaration
 /d917/f732.d(8): Error: no identifier for declarator void function(T*)
 
 I found a possible workaround. Its ugly as hell, but at least it works until 
 the bugs are fixed. 

There's no need for such ugly workarounds -- this is just a problem with
the *new* alias syntax. The old one accepts it (unless this changed recently):

alias extern(C) static void function(int*) Func_t;

artur


  1   2   >