PureBasic - The Perfect Cross-Platform & Native Development Language
Native, simply, fast, cross-platform, and quite powerful PL? Is it nothing? No, it isn't. It is PureBasic!
Why BASIC? Why this article?
No. I am not a BASIC adherent. I writing in more than 10 PLs including C#, Java, C++ and other main-stream PLs.
I don't think that PureBasic better than all of these PLs.
PureBasic isn't a best PL. C# is more convenient and powerful than PB for writing Windows applications. Python and Java is better for cross-platform development, not least because not compiling to platform-dependent executable format on many OSes.
But, if you want write native applications, not requiring a third-party dlls and platforms, or native and cross-platform applications, you can't use C#, Java, Python. You can use Delphi, a few C++ implementations, and a few more PLs. And, PureBasic is best for most native purposes. Really.
Also I am not a spammer advertising a commercial product on CodeProject. I do not work for the authors of PB. PB already enough popularly PL. I just help you orient that language is best for your purposes.
Why native & no 3rd-party? Why not .NET, JVM?
Where native and third-party independent development is necessary?
- Installers development. Installer shouldn't require a third-party platform. Also very undesirable to require a few third-party DLLs weighing a few MBs at all.
- SFX-archives development.
- CD-shells development.
- Drivers development. Driver just will not work if will require a .NET, JVM. high-level third-party libs.
- Adware and "legal adware" (with neccessary license agreement). Adware should eat a little CPU time, RAM and disk space and shouldn't require a third-party platform.
- Game development. There high performance needed. MS.NET or JVM are bad choice.
- And other soft requiring a performance and light weight.
- And "temporary" soft writing for experiments with undocument libx, hacks, etc. Tool for this should be quick, native and simply.
Why not Pure C/C++, Delphi, C++ Builder?
MessageBox(Str(2 + Int("2")));
intvar = Int("2");
intvar2 = 2 + intvar;
strvar = Str(intvar);
MessageBox(strvar);
// WARNING: compile in Unicode
#include <Windows.h>
#include <tchar.h>
#include <sstream>
#include <string>
// #pragma comment(lib, "user32.lib") --- for MessageBox, required if lib not added in the compiler options
using namespace std;
int main()
{
int intvar;
wistringstream s(_T("2"));
s >> intvar;
wostringstream ss;
ss << 2 + intvar;
wstring strvar = ss.str();
MessageBox(0, strvar.c_str(), _T(""), MB_OK);
return 0;
}
You should learn and write a much more to obtain the same result.
Delphi and C++ Builder aren't so hard. But they are paid (and very expensive) and creating quite large EXEs. Also, Delphi has long been used as malware creating tool - now few antiviruses suspects of Delphi EXEs in malware.
PureBasic: Compiler
PB designed for Windows, Linux, Mac OS and Amiga OS development. Have x86 and x64 versions.
PB compiling to platform-dependent binary format (EXE in Win) by platform-specified compiler version.
PB compiler at first translates a PB code into FASM code and next compiles this code by FASM compiler which provides a great performance and inline FASM using possibility.
PB compiler creating a light-weight (2 KB and more), fully native EXEs requiring only msvcrt.dll
and WinAPI (DependencyWalker screen):
msvcrt.dll pre-installed in Win 2000 and newer.
PureBasic: Standard Library
PB's standard library including a many of functions with different "cross-platformity" level (see documentation).
For example, it contains functions for use:
- BMP, JPEG, JPEG2000, PNG, TGA, TIFF formats
- Scintilla (code editing control)
- SQLite, PostgreSQL, ODBC databases
- Ogre 3D engine (!) It allow you to work with 2D and 3D graphics. Ogre lib integrared into PureBasic.
Also you can use a many of native OS API functions and interfaces, such as WinAPI on Windows and GDK/GTK on Linux.
PureBasic: Paradigm and Syntax
PB supports imperative and procedural paradigm.
PB officially not fully supports object-oriented paradigm today. In PB 5.20+ (23 July 2014) you can use Modules, like a Modules in VB 6.0 / VBA or static classes in C# / VB.NET. Also you can use "dirty tricks" such as http://forum.purebasic.com/english/viewtopic.php?f=12&t=61126 to imitate OOP in your applications.
In PB you shouldn't implement a main class or an entry point a main() in C++. You can just write a code in editor from its first to last line, such as in many of script PLs. It's very useful for "temporary" and "experimental" apps (see Why native & no 3rd-party? Why not .NET, JVM?)
Comments
Code() ; Comment as in the asm
Variables
Explicit integer variable definition:
x.i
Explicit integer variable definition and initialization:
x.i = 5
Explicit integer variable definition and using:
x.i
x = 5
y.i
y = x * 2 ; 10
Explicit string variable definition (via 2 ways!) and using:
str1.s = "Lorem" ; 1 way
str2$ = "ipsum" ; 2 way
str3$ = str1 + " " + str2$ ; Lorem ipsum
Fixed string:
str1.s{5}
str1 = "Lorem ipsum" ; Lorem
str2${5}
str2$ = "Lorem ipsum" ; Lorem
; Other variable types see in documentation.
Implicit variable definition:
x = 5
y = 2 * x ; 10
Variables convertation
Integer to string and back:
x = 5
str$ = Str(x)
x = 5 + Val(str$) ; 10
Double to string and back:
x.d = 3.2
str$ = StrD(x)
x = 2.5 + ValD(str$) ; 5.7
Double to string without 0 at end:
x.d = 3.2
str$ = StrD(x) ; 3.2000000000
str$ = Trim(str$, "0") ; 3.2
Constants
#x = 1
#y = "2"
#z = 3.14
Enumerations
Enumeration
#x ; 0
#y ; 1
#z ; 2
EndEnumeration
Ext. syntax:
Enumeration [<constant> [Step <constant>]]
#Constant1
#Constant2 [= <constant>]
#Constant3
...
EndEnumeration
Console Interface
OpenConsole()
Print("Hello world!")
Input() ; wait for key or input a value
Debug-time console interface
Debug "It will be printed in the debug output window"
Procedures
Procedure MsgBox(text$)
MessageRequester("", text$)
EndProcedure
MsgBox("Hello World")
With value return:
Procedure$ InputBox(text$)
ProcedureReturn InputRequester("", text$, "")
EndProcedure
name$ = InputBox("Print your name")
MessageRequester("", name$)
Data in EXE
This feature resembles resources in many other programming languages. But it isn't standard Windows resources and can't be readed by hackers using ResHacker or another resource viewer.
Numerical data:
Restore NumData
Read.l A
Read.l B
MessageRequester("", Str(A))
MessageRequester("", Str(B))
DataSection
NumData:
Data.l 1, 2
EndDataSection
String data:
Restore NumData
Read$ A$
Read$ B$
MessageRequester("", A$ + B$)
DataSection
NumData:
Data$ "Hello ", "world"
EndDataSection
Text file content:
Restore File1
Read.s File1Data$
MessageRequester("", File1Data$)
DataSection
File1:
IncludeBinary "file.txt"
EndDataSection
To be continued...
PureBasic: IDE
PureBasic IDE is very simply:
...but quite powerful:
Code regions (folding):
PureBasic: GUI
In PureBasic you can create GUI by 5 ways:
- Using PB's standard cross-platform GUI library only. Simplest way.
- Using native OS API only. For example, WinAPI allows you to create extemelly small executables, sometimes gives access to special features OS. Hardest and not always justified way.
- Combining PB's standard cross-platform GUI library and OS API if it needed. Prefered way in most cases.
- Using PB's standard cross-platform 3D GUI library. It's using 3D engine to draw game-like GUI and a bit like WPF in Microsoft .NET :) Prefered way for game and 3D graphics development.
- Using third-party GUI libraries based on 1, 2, 4 way or combining few ways. Backhanded way, depends on the quality of libraries.
Way 1 - Standard cross-platform GUI library
Enumeration
#btn1
EndEnumeration
OpenWindow(#PB_Any, 10, 50, 400, 200, "Lorem ipsum", #PB_Window_SystemMenu)
ButtonGadget(#btn1, 10, 10, 100, 25, "Button 1", 0)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
GadgetID = EventGadget()
If GadgetID = #btn1
MessageRequester("", "Button 1 clicked!")
EndIf
EndIf
Until Event = #PB_Event_CloseWindow


Way 2 - Native OS API
A simple (or not so? :)) WinAPI GUI program in PB:
; If you want to use in GUI not only latin characters, compile it in Unicode!
; Warning: exe size - it's very, very small!
Declare.l WndProc(hWnd, Msg, wParam, lParam) ; declare Window events callback
; Global vars
WindowClass.s = "WndClass1"
; Initialize Window Class
wc.WNDCLASSEX
wc\cbSize = SizeOf(WNDCLASSEX)
wc\hbrBackground = #COLOR_WINDOW
wc\hCursor = LoadCursor_(0, #IDC_ARROW)
wc\lpfnWndProc = @WndProc()
wc\lpszClassName = @WindowClass
; register Window Class
If RegisterClassEx_(@wc) = 0
MessageBox_(hWnd, "Can't register main window class.", "", #MB_ICONERROR)
End
EndIf
; create window
hWnd = CreateWindowEx_(0, WindowClass, "Lorem ipsum", #WS_SYSMENU, 10, 50, 400, 200, 0, 0, 0, 0)
If hWnd = 0
MessageBox_(hWnd, "Can't create main window.", "", #MB_ICONERROR)
End
EndIf
; create button and set it's font
hButton1 = CreateWindowEx_(0, "Button", "Button 1", #WS_CHILD | #WS_VISIBLE, 10, 10, 100, 25, hWnd, 0, 0, 0)
SendMessage_(hButton1, #WM_SETFONT, GetStockObject_(#DEFAULT_GUI_FONT), 1)
; show window
ShowWindow_(hWnd, #SW_SHOWDEFAULT)
UpdateWindow_(hWndMain)
; messages handling loop
While GetMessage_(msg.MSG, #Null, 0, 0 )
TranslateMessage_(msg)
DispatchMessage_(msg)
Wend
; window events callback
Procedure.l WndProc(hWnd, Msg, wParam, lParam)
Shared hButton1
Select Msg
Case #WM_COMMAND
If hButton1 = lParam
MessageBox_(hWnd, "Button 1 clicked!", "", #MB_OK)
EndIf
Case #WM_CLOSE
DestroyWindow_(hWnd)
Case #WM_DESTROY
PostQuitMessage_(0) : Result = 0
Default
Result = DefWindowProc_(hWnd, Msg, wParam, lParam)
EndSelect
ProcedureReturn Result
EndProcedure
PureBasic: Third-party Libraries
PureBasic: Community and Documentation
http://www.purebasic.fr/english/ (English)
http://forums.purebasic.com/german/ (German)
http://www.purebasic.fr/french/ (French)
http://purebasic.info/phpBB3ex/index.php (Russian)
http://www.cyberforum.ru/pure-basic/ (Russian)
http://purebasic.mybb.ru/ (Russian)
http://purebasic.ucoz.ru/forum (Russian)
http://www.purebasic.cn/forum.php (Chinese)
Documentation, tutorials, code samples
http://www.purebasic.com/documentation/
http://purearea.net/pb/CodeArchiv/CodeArchiv.html
http://pure-basic.narod.ru/ (Russian)
http://purebasic.info/Chapters/index.html (Russian)
http://purebasic.ucoz.ru/ (Russian)
http://mirashic.narod.ru/ (Russian)
http://purebasic.ucoz.com/ (Russian)
Alternative PB overview article