www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to do a function pointer to "malloc" and "free"?

reply rempas <rempas tutanota.com> writes:
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?
Oct 10 2021
next sibling parent reply Elmar <chrehme gmx.de> writes:
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 = &malloc; extern(C) void function(void*) freePointer = &free; ``` `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.
Oct 10 2021
parent reply rempas <rempas tutanota.com> writes:
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 = &malloc;
 extern(C) void function(void*) freePointer = &free;
 ```

 `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!
Oct 10 2021
parent reply Elmar <chrehme gmx.de> writes:
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) <function-signature>`. 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.
Oct 10 2021
next sibling parent reply rempas <rempas tutanota.com> writes:
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) <function-signature>`.

 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
Oct 10 2021
parent reply Elmar <chrehme gmx.de> writes:
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.
Oct 10 2021
parent rempas <rempas tutanota.com> writes:
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!
Oct 10 2021
prev sibling next sibling parent Elmar <chrehme gmx.de> writes:
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.
Oct 10 2021
prev sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
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.
Oct 10 2021
parent reply Elmar <chrehme gmx.de> writes:
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.
Oct 17 2021
parent Adam Ruppe <destructionator gmail.com> writes:
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. )
Oct 17 2021
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
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 = &malloc; ``` 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
Oct 11 2021