digitalmars.D.learn - How can a function pointer required to be extern(C)?
- rempas (28/28) Apr 12 2023 Sorry if the title doesn't make any sense, let me explain. So, I
- H. S. Teoh (18/54) Apr 12 2023 IMO this is a bug either in D's syntax or in the parser. I'd file an
- John Chapman (5/8) Apr 12 2023 You can also express it like this:
- rempas (6/10) Apr 13 2023 Thank you! This is how I was planning to do anyway because other
- rempas (8/22) Apr 13 2023 Thank you! As long as there is a way to do it with aliases, I
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(&this.thread_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(&this.thread_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?
Apr 12 2023
On Wed, Apr 12, 2023 at 08:23:51PM +0000, 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(&this.thread_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(&this.thread_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(&abc); pragma(msg, typeof(abc)); pragma(msg, typeof(&abc)); //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.
Apr 12 2023
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(&abc);You can also express it like this: ```d extern(C) alias FuncPtr = void* function(void*); ```
Apr 12 2023
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!
Apr 13 2023
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(&abc); pragma(msg, typeof(abc)); pragma(msg, typeof(&abc)); //void wrapper(extern(C) void* function(void*) callback) {} // NG void wrapper(FuncPtr callback) {} // OK pragma(msg, typeof(wrapper)); -------snip------- TThank 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!
Apr 13 2023