├── .gitignore ├── LICENSE ├── README.md ├── TobyPascal.pas ├── app.js ├── console ├── Console.dpr └── Console.dproj ├── doc ├── delphi-console.png └── delphi-gui.png ├── example ├── Project1.dpr ├── Project1.dproj ├── Unit1.dfm └── Unit1.pas └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Uncomment these types if you want even more clean repository. But be careful. 2 | # It can make harm to an existing project source. Read explanations below. 3 | # 4 | # Resource files are binaries containing manifest, project icon and version info. 5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. 6 | #*.res 7 | # 8 | # Type library file (binary). In old Delphi versions it should be stored. 9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. 10 | #*.tlb 11 | # 12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7. 13 | # Uncomment this if you are not using diagrams or use newer Delphi version. 14 | #*.ddp 15 | # 16 | # Visual LiveBindings file. Added in Delphi XE2. 17 | # Uncomment this if you are not using LiveBindings Designer. 18 | #*.vlb 19 | # 20 | # Deployment Manager configuration file for your project. Added in Delphi XE2. 21 | # Uncomment this if it is not mobile development and you do not use remote debug feature. 22 | #*.deployproj 23 | # 24 | # C++ object files produced when C/C++ Output file generation is configured. 25 | # Uncomment this if you are not using external objects (zlib library for example). 26 | #*.obj 27 | # 28 | 29 | # Delphi compiler-generated binaries (safe to delete) 30 | *.exe 31 | *.dll 32 | *.bpl 33 | *.bpi 34 | *.dcp 35 | *.so 36 | *.apk 37 | *.drc 38 | *.map 39 | *.dres 40 | *.rsm 41 | *.tds 42 | *.dcu 43 | *.lib 44 | *.a 45 | *.o 46 | *.ocx 47 | 48 | # Delphi autogenerated files (duplicated info) 49 | *.cfg 50 | *.hpp 51 | *Resource.rc 52 | 53 | # Delphi local files (user-specific info) 54 | *.local 55 | *.identcache 56 | *.projdata 57 | *.tvsconfig 58 | *.dsk 59 | 60 | # Delphi history and backups 61 | __history/ 62 | __recovery/ 63 | *.~* 64 | 65 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi) 66 | *.stat 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 ivere27 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # node-delphi 2 | 3 | ## GUI Example 4 | ![alt tag](https://github.com/ivere27/node-delphi/blob/master/doc/delphi-gui.png?raw=true) 5 | 6 | ## Console Example 7 | ![alt tag](https://github.com/ivere27/node-delphi/blob/master/doc/delphi-console.png?raw=true) 8 | 9 | 10 | you must copy tobynode.dll to the build directory(such as /Console/Win32/Debug/) 11 | 12 | ### download tobynode.dll 13 | * https://github.com/ivere27/archive/tree/master/tobynode/ 14 | 15 | ### or build tobynode.dll (includes toby and node.js) in debug mode 16 | * https://github.com/ivere27/toby/tree/master/vc_tobynode 17 | -------------------------------------------------------------------------------- /TobyPascal.pas: -------------------------------------------------------------------------------- 1 | unit TobyPascal; 2 | 3 | interface 4 | 5 | uses 6 | Classes, SysUtils, math, Windows; 7 | 8 | type 9 | TobyOnloadCB = procedure (isolate: Pointer); cdecl; 10 | TobyOnunloadCB = procedure (isolate: Pointer; exitCode: integer); cdecl; 11 | TobyHostcallCB = function (name, value: PAnsiChar):PAnsiChar; cdecl; 12 | 13 | TToby = class 14 | private 15 | started : boolean; 16 | H: HINST; 17 | constructor Init; 18 | public 19 | onLoad : TobyOnloadCB; 20 | onUnload : TobyOnunloadCB; 21 | onHostCall : TobyHostcallCB; 22 | 23 | InputPipeRead : THandle; 24 | InputPipeWrite : THandle; 25 | OutputPipeRead : THandle; 26 | OutputPipeWrite : THandle; 27 | ErrorPipeRead : THandle; 28 | ErrorPipeWrite : THandle; 29 | 30 | function start(processName, userScript: PAnsiChar) : boolean; 31 | function run(source: PAnsiChar) : PAnsiChar; 32 | procedure emit(name, value: PAnsiChar); 33 | class function Create: TToby; 34 | end; 35 | 36 | implementation 37 | var 38 | Singleton : TToby = nil; 39 | security : TSecurityAttributes; 40 | tobyInit:procedure (processName, userScript: PAnsiChar; 41 | tobyOnLoad: TobyOnloadCB; 42 | tobyOnUnload: TobyOnunloadCB; 43 | tobyHostCall: TobyHostcallCB); cdecl; 44 | tobyJSCompile:function (source, dest: PAnsiChar; n: integer):integer; cdecl; 45 | tobyJSCall:function (name, value, dest: PAnsiChar; n: integer):integer; cdecl; 46 | tobyJSEmit: function(name, value: PAnsiChar):integer; cdecl; 47 | 48 | 49 | procedure _OnLoad(isolate: Pointer); cdecl; 50 | begin 51 | //writeln(':: default tobyOnLoad called'); 52 | end; 53 | procedure _OnUnload(isolate: Pointer; exitCode: integer); cdecl; 54 | begin 55 | //writeln(':: default _OnUnload called'); 56 | end; 57 | function _OnHostCall(key,value: PAnsiChar):PAnsiChar; cdecl; 58 | begin 59 | //writeln(':: default tobyHostCall called. ', key, ' : ',value); 60 | exit(''); 61 | end; 62 | 63 | constructor TToby.Init; 64 | var 65 | stdout: THandle; 66 | begin 67 | // in case of 'git bash'(mingw) in windows 68 | stdout := GetStdHandle(Std_Output_Handle); 69 | Win32Check(stdout <> Invalid_Handle_Value); 70 | 71 | if (stdout = 0) then 72 | begin 73 | 74 | With security do 75 | begin 76 | nlength := SizeOf(TSecurityAttributes) ; 77 | binherithandle := true; 78 | lpsecuritydescriptor := nil; 79 | end; 80 | 81 | // FIXME : check returns 82 | CreatePipe(InputPipeRead, InputPipeWrite, @security, 0); 83 | CreatePipe(OutputPipeRead,OutputPipeWrite, @security, 0); 84 | CreatePipe(ErrorPipeRead, ErrorPipeWrite, @security, 0); 85 | SetStdHandle(Std_Input_Handle, InputPipeRead); 86 | SetStdHandle(Std_Output_Handle, OutputPipeWrite); 87 | SetStdHandle(Std_Error_Handle, ErrorPipeWrite); 88 | end; 89 | 90 | // dynamically load the dll. 91 | H := LoadLibrary('tobynode.dll'); 92 | 93 | if H<=0 then 94 | begin 95 | raise Exception.Create('tobynode.dll error!'); 96 | exit; 97 | end; 98 | 99 | @tobyInit := GetProcAddress(H, Pchar('tobyInit')); 100 | @tobyJSCompile := GetProcAddress(H, Pchar('tobyJSCompile')); 101 | @tobyJSCall := GetProcAddress(H, Pchar('tobyJSCall')); 102 | @tobyJSEmit := GetProcAddress(H, Pchar('tobyJSEmit')); 103 | 104 | started := false; 105 | 106 | // set default. 107 | onLoad := @_OnLoad; 108 | onUnload := @_OnUnload; 109 | onHostCall := @_OnHostCall; 110 | 111 | inherited Create; 112 | end; 113 | 114 | class function TToby.Create: TToby; 115 | begin 116 | if Singleton = nil then 117 | Singleton := TToby.Init; 118 | Result := Singleton; 119 | end; 120 | 121 | function TToby.start(processName, userScript: PAnsiChar) : boolean; 122 | begin 123 | if started = false then 124 | begin 125 | started := true; 126 | tobyInit(processName, userScript, onLoad, onUnload, onHostCall); 127 | exit(true); 128 | end; 129 | exit(false); 130 | end; 131 | 132 | 133 | procedure TToby.emit(name, value: PAnsiChar); 134 | begin 135 | tobyJSEmit(name, value); 136 | end; 137 | 138 | function TToby.run(source: PAnsiChar) : PAnsiChar; 139 | var 140 | dest: Array[0..1024] of AnsiChar; 141 | ret: integer; 142 | begin 143 | ret := tobyJSCompile(source, dest, Length(dest)); 144 | 145 | if (ret < 0) then 146 | writeln('** Error ', ret, ' ', dest); 147 | 148 | exit(dest); 149 | end; 150 | 151 | end. 152 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // print toby.version 4 | console.log(`node :: toby.version = ${toby.version}`); 5 | 6 | var num = 42; 7 | var foo = 'foo'; 8 | 9 | toby.on('test', function(x){ 10 | console.log(`node :: toby.on(test) = ${x}`); 11 | }); 12 | 13 | var result = toby.hostCall('dory', {num, foo}); 14 | console.log(`node :: toby.hostCall() = ${result}`); 15 | 16 | 17 | // var cluster = require('cluster'); 18 | // cluster.on('c', function(x){console.log(`node :: x`)}); 19 | // if (cluster.isMaster) { 20 | // console.log('node :: im master'); 21 | // cluster.fork(); 22 | // cluster.emit('c', 'greeting from parent :)') 23 | // } else { 24 | // console.log('node :: im slave. bye bye'); 25 | // cluster.emit('c','greeting from child :o') 26 | // process.exit(0); 27 | // } 28 | 29 | 30 | // exit after 2 secs 31 | (function(){setTimeout(function(){ 32 | process.exitCode = 42; 33 | },2000)})(); -------------------------------------------------------------------------------- /console/Console.dpr: -------------------------------------------------------------------------------- 1 | program Console; 2 | 3 | {$APPTYPE CONSOLE} 4 | 5 | {$R *.res} 6 | 7 | uses 8 | System.SysUtils, 9 | math, 10 | Classes, 11 | TobyPascal in '..\TobyPascal.pas'; 12 | 13 | var 14 | toby : TToby; 15 | 16 | procedure tobyOnLoad(isolate: Pointer); cdecl; 17 | begin 18 | writeln('host :: tobyOnLoad called'); 19 | 20 | toby.run('console.log("node :: hi~");'); 21 | end; 22 | procedure tobyOnUnload(isolate: Pointer; exitCode: Integer); cdecl; 23 | begin 24 | writeln('host :: tobyOnUnload called. ', exitCode); 25 | end; 26 | function tobyHostCall(key,value: PAnsiChar):PAnsiChar; cdecl; 27 | begin 28 | writeln('host :: tobyHostCall called. ', key, ' : ',value); 29 | exit('from tobyHostCall'); 30 | end; 31 | 32 | var 33 | i : integer = 0; 34 | begin 35 | try 36 | // start Toby 37 | toby := TToby.Create; 38 | toby.onLoad := @tobyOnLoad; 39 | toby.onUnload := @tobyOnUnload; 40 | toby.onHostCall := @tobyHostCall; 41 | 42 | //FIXME : replace the userScript with yours 43 | toby.start(PAnsiChar('toby'), PAnsiChar('require("../../../app.js")') ); 44 | 45 | while true do 46 | begin 47 | i:= i+1; 48 | toby.emit('test', PAnsiChar(IntToStr(i))); 49 | Sleep(1000); 50 | end; 51 | except 52 | on E: Exception do 53 | Writeln(E.ClassName, ': ', E.Message); 54 | end; 55 | end. 56 | -------------------------------------------------------------------------------- /console/Console.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {14435AD5-71BC-4DD0-A3B3-D6687B2DEE38} 4 | 18.1 5 | None 6 | Console.dpr 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Console 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Cfg_1 34 | true 35 | true 36 | 37 | 38 | true 39 | Base 40 | true 41 | 42 | 43 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 44 | Console 45 | .\$(Platform)\$(Config) 46 | .\$(Platform)\$(Config) 47 | false 48 | false 49 | false 50 | false 51 | false 52 | 53 | 54 | $(BDS)\bin\Artwork\Android\FM_SplashImage_470x320.png 55 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_96x96.png 56 | $(BDS)\bin\Artwork\Android\FM_SplashImage_426x320.png 57 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_48x48.png 58 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_144x144.png 59 | $(BDS)\bin\Artwork\Android\FM_SplashImage_960x720.png 60 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_72x72.png 61 | $(BDS)\bin\Artwork\Android\FM_SplashImage_640x480.png 62 | $(BDS)\bin\Artwork\Android\FM_LauncherIcon_36x36.png 63 | 64 | 65 | 1033 66 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 67 | true 68 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 69 | rtl;fmxase;NxInspectorRun_d10_1;vcl;CustomIPTransport;vclactnband;vcldsnap;IndyCore;IndySystem;NxInspectorDsgn_d10_1;vclx;NxCommonRun_d10_1;bindcomp;tethering;svnui;appanalytics;dsnap;NxDBGridRun_d10_1;Package1;bindcompvcl;NxDBGridDsgn_d10_1;vclimg;NxGridDsgn_d10_1;vcltouch;vclribbon;VclSmp;vcldb;bindcompfmx;svn;NxGridRun_d10_1;vclie;bindengine;dbrtl;IndyProtocols;NxCollectionRun_d10_1;fmx;fmxdae;NxCollectionDsgn_d10_1;xmlrtl;NxCommonDsgn_d10_1;fmxobj;vclwinx;inet;$(DCC_UsePackage) 70 | 71 | 72 | DEBUG;$(DCC_Define) 73 | true 74 | false 75 | true 76 | true 77 | true 78 | 79 | 80 | false 81 | 82 | 83 | false 84 | RELEASE;$(DCC_Define) 85 | 0 86 | 0 87 | 88 | 89 | 90 | MainSource 91 | 92 | 93 | 94 | Cfg_2 95 | Base 96 | 97 | 98 | Base 99 | 100 | 101 | Cfg_1 102 | Base 103 | 104 | 105 | 106 | Delphi.Personality.12 107 | Application 108 | 109 | 110 | 111 | Console.dpr 112 | 113 | 114 | 115 | False 116 | True 117 | 118 | 119 | 12 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /doc/delphi-console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivere27/node-delphi/15da48f70ee11c1b5d58f24e53cc46cf5feb338d/doc/delphi-console.png -------------------------------------------------------------------------------- /doc/delphi-gui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivere27/node-delphi/15da48f70ee11c1b5d58f24e53cc46cf5feb338d/doc/delphi-gui.png -------------------------------------------------------------------------------- /example/Project1.dpr: -------------------------------------------------------------------------------- 1 | program Project1; 2 | 3 | uses 4 | Vcl.Forms, 5 | Unit1 in 'Unit1.pas' {Form1}, 6 | TobyPascal in '..\TobyPascal.pas'; 7 | 8 | {$R *.res} 9 | 10 | begin 11 | Application.Initialize; 12 | Application.MainFormOnTaskbar := True; 13 | Application.CreateForm(TForm1, Form1); 14 | Application.Run; 15 | end. 16 | -------------------------------------------------------------------------------- /example/Project1.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {92A2DDEF-F9C0-42D3-B46D-B3FAF2F1CCC3} 4 | 18.1 5 | VCL 6 | Project1.dpr 7 | True 8 | Debug 9 | Win32 10 | 1 11 | Application 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Cfg_1 29 | true 30 | true 31 | 32 | 33 | true 34 | Base 35 | true 36 | 37 | 38 | true 39 | Cfg_2 40 | true 41 | true 42 | 43 | 44 | System;Xml;Data;Datasnap;Web;Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;$(DCC_Namespace) 45 | Project1 46 | $(BDS)\bin\delphi_PROJECTICON.ico 47 | .\$(Platform)\$(Config) 48 | .\$(Platform)\$(Config) 49 | false 50 | false 51 | false 52 | false 53 | false 54 | 55 | 56 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 57 | 1033 58 | rtl;NxInspectorRun_d10_1;vcl;vclactnband;vcldsnap;IndyCore;IndySystem;NxInspectorDsgn_d10_1;vclx;NxCommonRun_d10_1;bindcomp;tethering;svnui;appanalytics;dsnap;NxDBGridRun_d10_1;Package1;bindcompvcl;NxDBGridDsgn_d10_1;vclimg;NxGridDsgn_d10_1;vcltouch;vclribbon;VclSmp;vcldb;bindcompfmx;svn;NxGridRun_d10_1;bindengine;dbrtl;IndyProtocols;NxCollectionRun_d10_1;fmx;fmxdae;NxCollectionDsgn_d10_1;xmlrtl;NxCommonDsgn_d10_1;fmxobj;vclwinx;fmxase;$(DCC_UsePackage) 59 | true 60 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 61 | $(BDS)\bin\default_app.manifest 62 | 63 | 64 | toby.obj 65 | 1042 66 | DEBUG;$(DCC_Define) 67 | true 68 | false 69 | true 70 | true 71 | true 72 | 73 | 74 | true 75 | true 76 | false 77 | 78 | 79 | false 80 | RELEASE;$(DCC_Define) 81 | 0 82 | 0 83 | 84 | 85 | true 86 | true 87 | 88 | 89 | 90 | MainSource 91 | 92 | 93 |
Form1
94 |
95 | 96 | 97 | Cfg_2 98 | Base 99 | 100 | 101 | Base 102 | 103 | 104 | Cfg_1 105 | Base 106 | 107 |
108 | 109 | Delphi.Personality.12 110 | Application 111 | 112 | 113 | 114 | Project1.dpr 115 | 116 | 117 | 118 | True 119 | 120 | 121 | 12 122 | 123 | 124 | 125 |
126 | -------------------------------------------------------------------------------- /example/Unit1.dfm: -------------------------------------------------------------------------------- 1 | object Form1: TForm1 2 | Left = 0 3 | Top = 0 4 | Caption = 'Form1' 5 | ClientHeight = 552 6 | ClientWidth = 418 7 | Color = clBtnFace 8 | Font.Charset = DEFAULT_CHARSET 9 | Font.Color = clWindowText 10 | Font.Height = -11 11 | Font.Name = 'Tahoma' 12 | Font.Style = [] 13 | OldCreateOrder = False 14 | OnCreate = FormCreate 15 | PixelsPerInch = 96 16 | TextHeight = 13 17 | object Memo1: TMemo 18 | Left = 8 19 | Top = 8 20 | Width = 402 21 | Height = 337 22 | Lines.Strings = ( 23 | #39'use strict'#39 24 | '' 25 | 'var num = 42;' 26 | 'var foo = '#39'foo'#39';' 27 | '' 28 | 'toby.on('#39'test'#39', function(x){' 29 | ' toby.hostCall('#39'echo'#39' , x);' 30 | '});' 31 | '' 32 | 'var result = toby.hostCall('#39'dory'#39', {num, foo});' 33 | 'console.log(`node :: toby.hostCall() = ${result}`);' 34 | '' 35 | 'var http = require('#39'http'#39');' 36 | 'var req = http.get('#39'http://google.com'#39', function (res) {' 37 | ' var chunk = '#39#39';' 38 | ' res.on('#39'data'#39', function(d){ chunk += d;})' 39 | ' res.on('#39'end'#39', function(){' 40 | ' console.log(chunk);' 41 | ' });' 42 | '});' 43 | 'req.end();' 44 | '' 45 | 'setInterval(function(){},1000); // dummy loop') 46 | TabOrder = 0 47 | end 48 | object Memo2: TMemo 49 | Left = 8 50 | Top = 382 51 | Width = 402 52 | Height = 163 53 | TabOrder = 1 54 | end 55 | object Button1: TButton 56 | Left = 8 57 | Top = 351 58 | Width = 75 59 | Height = 25 60 | Caption = 'init node.js' 61 | TabOrder = 2 62 | OnClick = Button1Click 63 | end 64 | object Button2: TButton 65 | Left = 89 66 | Top = 351 67 | Width = 75 68 | Height = 25 69 | Caption = 'emit '#39'test'#39 70 | TabOrder = 3 71 | OnClick = Button2Click 72 | end 73 | object Timer1: TTimer 74 | Enabled = False 75 | OnTimer = Timer1Timer 76 | Left = 312 77 | Top = 352 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /example/Unit1.pas: -------------------------------------------------------------------------------- 1 | unit Unit1; 2 | 3 | interface 4 | 5 | uses 6 | Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 7 | Vcl.Controls, Vcl.Forms, Vcl.Dialogs, TobyPascal, Vcl.StdCtrls, Vcl.ExtCtrls; 8 | 9 | type 10 | TForm1 = class(TForm) 11 | Memo1: TMemo; 12 | Memo2: TMemo; 13 | Button1: TButton; 14 | Button2: TButton; 15 | Timer1: TTimer; 16 | procedure FormCreate(Sender: TObject); 17 | procedure Button1Click(Sender: TObject); 18 | procedure Button2Click(Sender: TObject); 19 | procedure Timer1Timer(Sender: TObject); 20 | private 21 | { Private declarations } 22 | public 23 | { Public declarations } 24 | end; 25 | 26 | var 27 | Form1: TForm1; 28 | toby : TToby; 29 | 30 | implementation 31 | 32 | {$R *.dfm} 33 | 34 | procedure LOG(line: String); 35 | begin 36 | Form1.Memo2.Lines.Add(line); 37 | end; 38 | 39 | procedure tobyOnLoad(isolate: Pointer); cdecl; 40 | begin 41 | LOG('host :: tobyOnLoad called'); 42 | end; 43 | procedure tobyOnUnload(isolate: Pointer; exitCode: Integer); cdecl; 44 | begin 45 | LOG('host :: tobyOnUnload called. ' + IntToStr(exitCode)); 46 | end; 47 | function tobyHostCall(key,value: PAnsiChar):PAnsiChar; cdecl; 48 | begin 49 | LOG('host :: tobyHostCall called. ' + key + ' : ' + value); 50 | exit(PAnsiChar('from tobyHostCall')); 51 | end; 52 | 53 | procedure TForm1.Button1Click(Sender: TObject); 54 | begin 55 | toby.start(PAnsiChar('toby'), PAnsiChar(AnsiString(Memo1.Text))); 56 | Timer1.Enabled := true; 57 | end; 58 | 59 | procedure TForm1.Button2Click(Sender: TObject); 60 | begin 61 | toby.emit(PAnsiChar('test'), PAnsiChar('hi toby')); 62 | end; 63 | 64 | procedure TForm1.FormCreate(Sender: TObject); 65 | begin 66 | 67 | // start Toby 68 | toby := TToby.Create; 69 | toby.onLoad := @tobyOnLoad; 70 | toby.onUnLoad := @tobyOnUnload; 71 | toby.onHostCall := @tobyHostCall; 72 | end; 73 | 74 | // FIXME : workaround. should be async 75 | procedure TForm1.Timer1Timer(Sender: TObject); 76 | var 77 | TextBuffer: array[1..32767] of AnsiChar; 78 | TextString: String; 79 | BytesRead: DWord; 80 | PipeSize: Integer; 81 | BytesRem: DWord; 82 | begin 83 | PipeSize := Sizeof(TextBuffer); 84 | 85 | PeekNamedPipe(Toby.OutputPipeRead, nil, PipeSize, @BytesRead, @PipeSize, @BytesRem); 86 | if BytesRead > 0 then 87 | begin 88 | ReadFile(Toby.OutputPipeRead, TextBuffer, PipeSize, BytesRead, nil); 89 | OemToChar(@TextBuffer, @TextBuffer); 90 | TextString := String(TextBuffer); 91 | SetLength(TextString, BytesRead); 92 | LOG(TextString); 93 | end; 94 | 95 | end; 96 | 97 | end. 98 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "delphi", 3 | "version": "0.0.2", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/ivere27/node-delphi.git" 12 | }, 13 | "author": "", 14 | "license": "AGPL", 15 | "bugs": { 16 | "url": "https://github.com/ivere27/node-delphi/issues" 17 | }, 18 | "homepage": "https://github.com/ivere27/node-delphi#readme" 19 | } 20 | --------------------------------------------------------------------------------