Automatically import c headers
Automatically import c headers
Now that we've got a c backend we could really use an automated header converter.
So we could just declare xincludefilec and have it preprocess the header and import the functions and constants.
It's been in my to hard basket for a number of years but now that we have gcc tool chain on all platforms it now makes it feasable to do.
So we could just declare xincludefilec and have it preprocess the header and import the functions and constants.
It's been in my to hard basket for a number of years but now that we have gcc tool chain on all platforms it now makes it feasable to do.
-
- Enthusiast
- Posts: 557
- Joined: Wed Sep 25, 2019 10:18 am
Re: Automatically import c headers
After which line in purebasic.c do you want to insert #include "file.h" with XIncludeFileC "file.h"?
purebasic.c example
purebasic.c example
Re: Automatically import c headers
Your not actually including an .h file
It would be the resultant .pbi preprocessed and translated to pb so it can be where ever you want.
It would be the resultant .pbi preprocessed and translated to pb so it can be where ever you want.
Re: Automatically import c headers
This would be a great feature, but in the headers I use, there are many C macros and #if's.
It forces me to tweak the converted pbi file for naming conflicts and duplicate prototypes for 'A'/'W' strings, etc.
Would this handle that complexity?
It forces me to tweak the converted pbi file for naming conflicts and duplicate prototypes for 'A'/'W' strings, etc.
Would this handle that complexity?
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: Automatically import c headers
As a compiler tool probably not. But we could always name space the functions in the headers.
When you preprocess an .h file it includes everything required in one file for the target. With all macros and compiler ifs expanded and all types are resolved to their respective base c types.
It doesn't look nice but it's much easier to parse.
You would need to pass the necessary defines on the command line to gcc to get around the A/W string issue.
When you preprocess an .h file it includes everything required in one file for the target. With all macros and compiler ifs expanded and all types are resolved to their respective base c types.
It doesn't look nice but it's much easier to parse.
You would need to pass the necessary defines on the command line to gcc to get around the A/W string issue.
- the.weavster
- Addict
- Posts: 1537
- Joined: Thu Jul 03, 2003 6:53 pm
- Location: England
Re: Automatically import c headers
I was hoping for something similar to SpiderBasic's EnableJS / DisableJS
So including a C header would be:
So including a C header would be:
Code: Select all
EnableC
#include "myheader.h"
DisableC
-
- Enthusiast
- Posts: 557
- Joined: Wed Sep 25, 2019 10:18 am
Re: Automatically import c headers
Code: Select all
; Demo #include "myheader.h"
!#include "/tmp/myheader.h" // Please adapt.
Procedure test()
!#include "/tmp/myheader.h" // Please adapt.
EndProcedure
test()
CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant)
CompilerError "Please use PureBasic Version 6.00 Beta1"
CompilerElseIf #PB_Compiler_Backend<>#PB_Backend_C
CompilerError "Please use Compiler-Option C Backend."
CompilerEndIf
Code: Select all
//...
int main(int argc, char* argv[]) {
PB_ArgC = argc;
PB_ArgV = argv;
SYS_InitPureBasic();
//
// !#include "/tmp/myheader.h" // Please adapt.
#include "/tmp/myheader.h" // Please adapt.
// test()
integer rr0=f_test();
//
// CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant)
SYS_Quit();
}
//...
// Procedure test()
Static integer f_test() {
integer r=0;
// !#include "/tmp/myheader.h" // Please adapt.
#include "/tmp/myheader.h" // Please adapt.
// EndProcedure
End:
Return r;
}
//...
Re: Automatically import c headers
@the.weavster
I'm not sure how that works are the functions accessible from pb then or only js.
I would much prefer that the c is accessible from pb and to port the headers. But It's not that easy, c is quite complex to parse but it would opens up the whole c eco system to pb users which would be a major win. Especially for the raspberry pi and Linux.
I'm not sure how that works are the functions accessible from pb then or only js.
I would much prefer that the c is accessible from pb and to port the headers. But It's not that easy, c is quite complex to parse but it would opens up the whole c eco system to pb users which would be a major win. Especially for the raspberry pi and Linux.
Re: Automatically import c headers
Ok this works on linux, it's not very pretty but it works.
Code: Select all
CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant)
CompilerError "Please use PureBasic Version 6.00 Beta1"
CompilerElseIf #PB_Compiler_Backend<>#PB_Backend_C
CompilerError "Please use Compiler-Option C Backend."
CompilerEndIf
ImportC "-lportaudio" : EndImport
!#include "/usr/include/portaudio.h" // Please adapt.
Structure paTestData
left_phase.f;
right_phase.f;
EndStructure
Global *stream;
Global err
Global num_seconds= 4;
Global sample_rate = 44100;
Global *output
Global mData.PaTestData
;** This routine will be called by the PortAudio engine when audio is needed.
;** It may called at interrupt level on some machines so don't do anything
;** that could mess up the system like calling malloc() Or free().
Procedure patestCallback(*inputBuffer,*outputBuffer,framesPerBuffer,*timeInfo,statusFlags,*userData.paTestData)
*out.float = *outputBuffer;
Protected i
For i=0 To framesPerBuffer
*out\f = *userData\left_phase; /* left */
*out+4
*out\f = *userData\right_phase; /* right */
*out+4
;/* Generate simple sawtooth phaser that ranges between -1.0 And 1.0. */
*userData\left_phase + 0.01
;/* When signal reaches top, drop back down. */
If *userData\left_phase >= 1.0
*userData\left_phase - 1.0
EndIf
;higher pitch so we can distinguish left And right. */
*userData\right_phase + 0.03
If *userData\right_phase >= 1.0
*userData\right_phase = -1.0;
EndIf
Next
EndProcedure ;
Procedure pa_Init()
Protected ret
!v_ret = Pa_Initialize();
ProcedureReturn ret
EndProcedure
Procedure Pa_Terminate()
!Pa_Terminate();
EndProcedure
Global paCallback = @patestCallback()
Debug "PortAudio Test: output sawtooth wave."
!v_err = Pa_Initialize();
If err <> 0
Goto error;
EndIf
!v_err = Pa_OpenDefaultStream(&p_stream,0,2,paFloat32,v_sample_rate,16,v_pacallback,&v_mdata);
If err <> 0
Goto error;
EndIf
!v_err = Pa_StartStream(p_stream);
If err <> 0
Goto error;
EndIf
!Pa_Sleep(v_num_seconds*1000);
!v_err = Pa_StopStream(p_stream );
If err <> 0
Goto error;
EndIf
!v_err = Pa_CloseStream(p_stream);
If err <> paNoError
Goto error;
EndIf
Pa_Terminate();
Debug "Test finished"
End
error:
Pa_Terminate();
Debug "An error occured while using the portaudio stream"
Debug "error number " + Str(err)
!p_output = Pa_GetErrorText(v_err);
Debug PeekS(*output,-1,#PB_UTF8)
- the.weavster
- Addict
- Posts: 1537
- Joined: Thu Jul 03, 2003 6:53 pm
- Location: England
Re: Automatically import c headers
Actually looking at your and juergen's code above I think maybe what I'm asking for already works just by using the ! line prefix
Just to clarify though...
A variable works with the v_ prefix, exactly as it does in SpiderBasic
Code: Select all
Protected ret
!v_ret = Pa_Initialize();
but does the p_ prefix in C denote a pointer declared in PB?:
Code: Select all
Global *output
...
!p_output = Pa_GetErrorText(v_err);
Re: Automatically import c headers
Yes p_pointer and v_var. Constants need to be globals unless you only use the c define inline
-
- Enthusiast
- Posts: 557
- Joined: Wed Sep 25, 2019 10:18 am
Re: Automatically import c headers
Using Procedure generates error: conflicting types For ‘Pa_GetErrorText’:
pa_front2.c
Code: Select all
; ImportC, #include DemoErr with const char *Pa_GetErrorText( PaError errorCode )
ImportC "/tmp/pa_front2.o" : EndImport ; Please adapt.
!#include "/tmp/portaudio/include/portaudio.h" // Please adapt.
Procedure.s DemoErr(err)
;!#include "/tmp/portaudio/include/portaudio.h" // Please adapt.
Protected *output
!p_output = Pa_GetErrorText(v_err);
ProcedureReturn PeekS(*output,-1,#PB_UTF8)
EndProcedure
s.s=DemoErr(0) ; paNoError
Debug s
CompilerIf Not Defined(PB_Compiler_Backend,#PB_Constant)
CompilerError "Please use PureBasic Version 6.00 Beta1"
CompilerElseIf #PB_Compiler_Backend<>#PB_Backend_C
CompilerError "Please use Compiler-Option C Backend."
CompilerEndIf
; with #inclcude after ImportC without #include in Procedure
; Error: Assembler
; error: conflicting types For ‘Pa_GetErrorText’
; const char *Pa_GetErrorText( PaError errorCode );
; ^~~~~~~~~~~~~~~
; purebasic.c:87:12: note: previous implicit declaration of ‘Pa_GetErrorText’ was here
; p_output = Pa_GetErrorText(v_err);
; ^~~~~~~~~~~~~~~
; purebasic.c: In function ‘SYS_Quit’:
; purebasic.c:139:1: warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]
; exit(PB_ExitCode);
; ^~~~
; purebasic.c:139:1: warning: incompatible implicit declaration of built-in function ‘exit’
; purebasic.c:139:1: note: include ‘<stdlib.h>’ Or provide a declaration of ‘exit’
; with #include in Procedure
; Success
Code: Select all
#include "portaudio.h"
const char *Pa_GetErrorText( PaError errorCode )
{
const char *result;
switch( errorCode )
{
case paNoError: result = "Success"; break;
case paNotInitialized: result = "PortAudio not initialized"; break;
/** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError. see: http://www.portaudio.com/trac/ticket/114 */
case paUnanticipatedHostError: result = "Unanticipated host error"; break;
case paInvalidChannelCount: result = "Invalid number of channels"; break;
case paInvalidSampleRate: result = "Invalid sample rate"; break;
case paInvalidDevice: result = "Invalid device"; break;
case paInvalidFlag: result = "Invalid flag"; break;
case paSampleFormatNotSupported: result = "Sample format not supported"; break;
case paBadIODeviceCombination: result = "Illegal combination of I/O devices"; break;
case paInsufficientMemory: result = "Insufficient memory"; break;
case paBufferTooBig: result = "Buffer too big"; break;
case paBufferTooSmall: result = "Buffer too small"; break;
case paNullCallback: result = "No callback routine specified"; break;
case paBadStreamPtr: result = "Invalid stream pointer"; break;
case paTimedOut: result = "Wait timed out"; break;
case paInternalError: result = "Internal PortAudio error"; break;
case paDeviceUnavailable: result = "Device unavailable"; break;
case paIncompatibleHostApiSpecificStreamInfo: result = "Incompatible host API specific stream info"; break;
case paStreamIsStopped: result = "Stream is stopped"; break;
case paStreamIsNotStopped: result = "Stream is not stopped"; break;
case paInputOverflowed: result = "Input overflowed"; break;
case paOutputUnderflowed: result = "Output underflowed"; break;
case paHostApiNotFound: result = "Host API not found"; break;
case paInvalidHostApi: result = "Invalid host API"; break;
case paCanNotReadFromACallbackStream: result = "Can't read from a callback stream"; break;
case paCanNotWriteToACallbackStream: result = "Can't write to a callback stream"; break;
case paCanNotReadFromAnOutputOnlyStream: result = "Can't read from an output only stream"; break;
case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break;
case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
case paBadBufferPtr: result = "Bad buffer pointer"; break;
default:
if( errorCode > 0 )
result = "Invalid error code (value greater than zero)";
else
result = "Invalid error code";
break;
}
return result;
}
Re: Automatically import c headers
Im not sure what the problem is. How did you compile the c code?
Maybe i should find another library that's easy to find binaries for windows and osx.
Maybe i should find another library that's easy to find binaries for windows and osx.
-
- Enthusiast
- Posts: 557
- Joined: Wed Sep 25, 2019 10:18 am
Re: Automatically import c headers
Please check if TCC would be suitable for this?
Re: Automatically import c headers
Libtcc may be usable, tcc has been around for awhile I will look into it. In the mean time I've found a python tool that converts to json its written by one of the developers of llvm and after a quick look It should be possible to use it and port the json to pb.