www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why I get delegate when passing address of function?

reply Injeckt <vinsentlou9 gmail.com> writes:
I have a one class and two modificators, where in "public" 
function I'm calling CreateThread with address of the 
ClientThread function which stored in same class, but in 
"private" modificator.

And i get this error:
Error: cannot pass argument `&this.ClientThread` of type `extern 
(Windows) uint delegate(void* param)` to parameter `extern 
(Windows) uint function(void*)  system`.


     public:
         void server_init() {
             CreateThread(NULL, 0, &this.ClientThread, 
cast(PVOID)clientSocket, 0, NULL);
         }

     private:
         extern(Windows)
         DWORD ClientThread(PVOID param) {
             this.log("\nHello from thread\n");
             return 0;
         }
Sep 11 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 11 September 2022 at 09:02:31 UTC, Injeckt wrote:
 I have a one class and two modificators, where in "public" 
 function I'm calling CreateThread with address of the 
 ClientThread function which stored in same class, but in 
 "private" modificator.

 And i get this error:
 Error: cannot pass argument `&this.ClientThread` of type 
 `extern (Windows) uint delegate(void* param)` to parameter 
 `extern (Windows) uint function(void*)  system`.
Pointers to non-static member functions always produce a delegate. Otherwise, you wouldn't be able to access the class instance's members.
Sep 11 2022
parent reply Mike Parker <aldacron gmail.com> writes:
On Sunday, 11 September 2022 at 09:15:11 UTC, Mike Parker wrote:

 Pointers to non-static member functions always produce a 
 delegate. Otherwise, you wouldn't be able to access the class 
 instance's members.
Reference: https://dlang.org/spec/function.html#closures
Sep 11 2022
parent reply Injeckt <vinsentlou9 gmail.com> writes:
On Sunday, 11 September 2022 at 09:29:23 UTC, Mike Parker wrote:
 On Sunday, 11 September 2022 at 09:15:11 UTC, Mike Parker wrote:

 Pointers to non-static member functions always produce a 
 delegate. Otherwise, you wouldn't be able to access the class 
 instance's members.
Reference: https://dlang.org/spec/function.html#closures
And what I should do to pass non-static function? I'm trying get function with .funcptr property, but it still doesn't work. CreateThread(NULL, 0, this.ClientThread.funcptr, cast(PVOID)clientSocket, 0, NULL); Error: function `_server.Server.ClientThread(void* param)` is not callable using argument types `()`. too few arguments, expected `1`, got `0` Is there ways to do that with non-static function or anyway I must make it static?
Sep 11 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/11/22 02:54, Injeckt wrote:

 And what I should do to pass non-static function?
You can combine your class object with other arguments and your thread function will know how to unwrap your class object to call its member function: import std.stdio; // I am not on Windows, so I am making it non-D another way // Let's assume this is what the library wants from us alias MyThreadFunc = uint function(void*); // Let's assume this is what the library provides extern (C) void libraryCreateThread(MyThreadFunc func, void* param) { writeln("The libraryCreateThread is starting our function"); func(param); } // This is my class class C { string s; // This is the function I want to be called void myClientThread(void* param) { writeln("The desired member function is here"); writeln("the member: ", s); // At this point we know the extra argument shoud be an // int (that's why main used one) auto arg = *cast(int*)param; writeln("the extra argument: ", arg); } } // We have to play along with what the library wants // It wants a 'function', so here is one: // (This could be a static member function) uint myNonMemberThreadFunc(void* param) { writeln("Our function is making the param useful..."); // See MyThreadArgs below auto args = *cast(MyThreadArgs*)param; writeln("... and calling our member function"); args.c.myClientThread(args.extraArg); return 0; } // This combines a class instance (which is a pointer behind the scene) // and any other argument struct MyThreadArgs { C c; void* extraArg; } void main() { auto c = new C(); c.s = "the class member"; // Assuming some extra argument int mainArg = 42; // Combine with the class object; this may have to be on the heap auto args = MyThreadArgs(c, &mainArg); // Do what the library wants libraryCreateThread(&myNonMemberThreadFunc, cast(void*)&args); }
 Error: function `_server.Server.ClientThread(void* param)` is not
 callable using argument types `()`. too few arguments, expected `1`, got
 `0`
That looks like the same problem you had a couple of days ago: The name of the function is not a function pointer in D but is a call to it: - foo: The same thing as foo() - &foo: 'function' Ali
Sep 11 2022
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 9/11/22 09:26, Ali Çehreli wrote:

 // This combines a class instance (which is a pointer behind the scene)
      // Combine with the class object
In both places I meant "class variable". Ali
Sep 11 2022
prev sibling parent Injeckt <vinsentlou9 gmail.com> writes:
On Sunday, 11 September 2022 at 16:26:10 UTC, Ali Çehreli wrote:
 On 9/11/22 02:54, Injeckt wrote:

 [...]
You can combine your class object with other arguments and your thread function will know how to unwrap your class object to call its member function: [...]
Thank you for help, comrade. I just passed class object as a parameter and now I got "context".
Sep 11 2022