www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to call a C function from D that takes a FILE * as an argument?

reply Joe <jma freedomcircle.com> writes:
The subject basically says it all. The C function uses the 
argument to call fprintf and also passes it to other functions 
where it's used to call fileno, fprintf or putc.
Jul 03 2018
parent reply Seb <seb wilzba.ch> writes:
On Wednesday, 4 July 2018 at 01:06:36 UTC, Joe wrote:
 The subject basically says it all. The C function uses the 
 argument to call fprintf and also passes it to other functions 
 where it's used to call fileno, fprintf or putc.
Like you would with C's fprintf (https://dlang.org/phobos/core_stdc_stdio.html#.fprintf). For example, this is a valid D program: --- void main(string[] args) { import core.stdc.stdio; FILE* pFile; int n; char[100] name; pFile = fopen ("myfile.txt","w"); // string literals are zero-terminated for (n=0 ; n<3 ; n++) { puts("please, enter a name: "); gets(name.ptr); fprintf pFile, "Name %d [%-10.10s]\n",n+1,name.ptr); } fclose(pFile); } --- (example from http://www.cplusplus.com/reference/cstdio/fprintf) So just add the declaration to your D file: --- extern(C) void myCfunction(FILE* stream); --- and as long as you link your program into the D binary, you should be good to go. For larger C bases, tools like dstep or dpp can help translating C/C++ header files to D.
Jul 03 2018
parent reply Joe <jma freedomcircle.com> writes:
On Wednesday, 4 July 2018 at 01:58:15 UTC, Seb wrote:
 So just add the declaration to your D file:

 ---
 extern(C) void myCfunction(FILE* stream);
 ---
I do have a similar declaration in D. It appears the problem is that the C program I'm trying to convert passes stdout as the argument and the D compiler complains somewhat like the following: Error: function foo.main.myCfunction (shared(_IO_FILE)* stream) is not callable using argument types (File) So I guess the question is what to pass instead of stdout.
Jul 03 2018
parent reply Seb <seb wilzba.ch> writes:
On Wednesday, 4 July 2018 at 02:08:11 UTC, Joe wrote:
 On Wednesday, 4 July 2018 at 01:58:15 UTC, Seb wrote:
 So just add the declaration to your D file:

 ---
 extern(C) void myCfunction(FILE* stream);
 ---
I do have a similar declaration in D. It appears the problem is that the C program I'm trying to convert passes stdout as the argument and the D compiler complains somewhat like the following: Error: function foo.main.myCfunction (shared(_IO_FILE)* stream) is not callable using argument types (File) So I guess the question is what to pass instead of stdout.
Hmm, calling e.g. fprintf with stdout should just work: --- void main() { import core.stdc.stdio; fprintf(stdout, "Hello %s", "world".ptr); } --- Could you maybe provide your whole code?
Jul 03 2018
parent reply Joe <jma freedomcircle.com> writes:
On Wednesday, 4 July 2018 at 02:16:00 UTC, Seb wrote:
 Hmm, calling e.g. fprintf with stdout should just work:

 ---
 void main()
 {
     import core.stdc.stdio;
     fprintf(stdout, "Hello %s", "world".ptr);
 }
 ---

 Could you maybe provide your whole code?
This short test program shows the error: --- import std.stdio; void main() { extern (C) void list(FILE *fd); list(stdout); } --- Now I fixed this by changing the import to core.stdc.stdio. I guess the problem is if you import std.stdio (which brings in the other one), there are two slightly incompatible stdout's and the D takes precedence.
Jul 03 2018
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Wednesday, 4 July 2018 at 02:54:47 UTC, Joe wrote:
 Now I fixed this by changing the import to core.stdc.stdio. I 
 guess the problem is if you import std.stdio (which brings in 
 the other one), there are two slightly incompatible stdout's 
 and the D takes precedence.
If you import both modules (or even I think if just the D std.stdio, since it publicly imports the other), you can specify the C one by using its full name: core.stdc.stdio.stdout where you use it. of course you can also alias it to something shorter.
Jul 03 2018
prev sibling parent WebFreak001 <d.forum webfreak.org> writes:
On Wednesday, 4 July 2018 at 02:54:47 UTC, Joe wrote:
 On Wednesday, 4 July 2018 at 02:16:00 UTC, Seb wrote:
 Hmm, calling e.g. fprintf with stdout should just work:

 ---
 void main()
 {
     import core.stdc.stdio;
     fprintf(stdout, "Hello %s", "world".ptr);
 }
 ---

 Could you maybe provide your whole code?
This short test program shows the error: --- import std.stdio; void main() { extern (C) void list(FILE *fd); list(stdout); } --- Now I fixed this by changing the import to core.stdc.stdio. I guess the problem is if you import std.stdio (which brings in the other one), there are two slightly incompatible stdout's and the D takes precedence.
`stdout.getFP` (stdout is of the D std.stdio.File struct type and with getFP you get the underlying FILE*)
Jul 04 2018