Skip to content

Commit

Permalink
Call .NET from Delphi using Python
Browse files Browse the repository at this point in the history
  • Loading branch information
PyjaErskell committed Dec 9, 2019
1 parent 1b66172 commit 0a97f77
Show file tree
Hide file tree
Showing 8 changed files with 1,263 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
unit Global;

interface

uses
ComObj, System.SysUtils, Vcl.Forms;

var
gu_r: Variant;

function gf_re ( x_str: String ) : Variant;

implementation

function gf_re ( x_str: String ) : Variant;
begin
result := gu_r .Eval (x_str);
end;

initialization
gu_r := CreateOleObject ('ScriptControl');
gu_r.Language := 'RubyScript';
gf_re (
'lambda { |x_milo_pn|' + Chr(10) +
' pu_src_pn = [ x_milo_pn, "src", "ruby" ] .join "\\"' + Chr(10) +
' $LOAD_PATH .unshift pu_src_pn unless $LOAD_PATH .include? pu_src_pn' + Chr(10) +
' $GC_MILO_PN = x_milo_pn' + Chr(10) +
' require "SToa"' + Chr(10) +
'}'
) .call ( ExtractFileDir ( ExtractFileDir (Application.ExeName) ) );

finalization

end.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
program SToa;

uses
Vcl.Forms,
WMain in 'WMain.pas' {wu_main},
Global in 'Global.pas';

{$R *.res}

begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(Twu_main, wu_main);
Application.Run;
end.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
object wu_main: Twu_main
Left = 0
Top = 0
Caption = 'SToa'
ClientHeight = 213
ClientWidth = 606
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object wu_lbx: TListBox
Left = 0
Top = 0
Width = 606
Height = 213
Align = alClient
ItemHeight = 13
TabOrder = 0
ExplicitHeight = 202
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
unit WMain;

interface

uses
Global,
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
Twu_main = class(TForm)
wu_lbx: TListBox;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
wu_main: Twu_main;

implementation

{$R *.dfm}

procedure Twu_main.FormCreate(Sender: TObject);
begin
with wu_lbx .Items do begin
wu_main.Caption := Format ( '%s : %s', [ gf_re ('$GC_OLIM_NM'), gf_re ('$GC_TONO_NM') ] );
Add ( Format ( 'RTL Version => %f', [RTLVersion] ) );
Add ( Format ( 'Ruby version => %s', [ gf_re ('RUBY_VERSION') ] ) );
Add ( Format ( 'Java version => %s', [ gf_re ('$CjSystem') .getProperty ('java.version') ] ) );
Add ( Format ( 'Groovy version => %s', [ gf_re ( '$CjString .valueOf $jf_ge .call "GroovySystem.version"' ) ] ) );
Add ( Format ( 'Python version => %s', [ gf_re ( '$CjString .valueOf $ju_t .getValue "GC_PYTHON_VR"' ) ] ) );
Add ( Format ( 'PyQt version => %s', [ gf_re ( '$CjString .valueOf $ju_t .getValue "GC_PYQT_VR"' ) ] ) );
Add ( Format ( '.NET version => %s', [ gf_re ( '$CjString .valueOf $ju_t .getValue "GC_DOTNET_VR"' ) ] ) );
Add ( Format ( 'Groovy hello (English) => %s', [ gf_re ('$sf_g_hello') .call ( 'groovy-', 10 ) ] ) );
Add ( Format ( 'Groovy hello (Koean) => %s', [ gf_re ('$sf_g_hello') .call ( '±×·çºñ-', 10 ) ] ) );
Add ( Format ( 'Groovy sum of numbers => %s', [ gf_re ('$sf_g_sum') .call ( 700000000, 12, 49, 15, 51, 94, 21, 63 ) ] ) );
Add ( Format ( 'Python hello (English) => %s', [ gf_re ('$sf_t_hello') .call ( 'python-', 10 ) ] ) );
Add ( Format ( 'Python hello (Korea) => %s', [ gf_re ('$sf_t_hello') .call ( 'ÆÄÀ̽ã-', 10 ) ] ) );
Add ( Format ( 'Python sum of numbers => %s', [ gf_re ('$sf_t_sum') .call ( 700000000, 12, 49, 15, 51, 94, 21, 63 ) ] ) );
Add ( Format ( 'System.String.Format (English) => %s', [ gf_re ('$sf_n_format') .call ( 'Hello {0} !!!', 'DotNet' ) ] ) );
Add ( Format ( 'System.String.Format (Korea) => %s', [ gf_re ('$sf_n_format') .call ( 'Hello {0} !!!', '´å³Ý' ) ] ) );
end;
end;

end.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#---------------------------------------------------------------
# Global
#---------------------------------------------------------------

import sys

sys.dont_write_bytecode = True

import os

os.environ['QT_PLUGIN_PATH'] = GC_QT_PLUGIN_PATH
os.environ['QT_AUTO_SCREEN_SCALE_FACTOR'] = '1' # High-DPI Support in Qt 5.6

import platform
from PyQt5 import QtCore

GC_PYTHON_VR = platform .python_version ()
GC_PYQT_VR = QtCore .qVersion ()

import clr
import System

GC_DOTNET_VR = System.Environment.Version .ToString ()

#---------------------------------------------------------------
# Your Source
#---------------------------------------------------------------

def sf_hello ( x_str, x_no ) : return 'Hello {} !!!' .format ( x_str * x_no )
def sf_sum ( * x_args ) : return sum (x_args)
sf_n_format = System.String.Format
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#---------------------------------------------------------------
# Global
#---------------------------------------------------------------

$GC_ENCODING = 'EUC-KR'

$GC_FOSA = File::ALT_SEPARATOR || File::SEPARATOR # (fo)lder (s)ep(a)rator
$GC_PASA = File::PATH_SEPARATOR # (pa)th (s)ep(a)rator

$gf_pj = lambda { | * x_args | x_args .join $GC_FOSA } # (p)ath (j)oin
$gf_bn = lambda { |x_fn| File .basename x_fn } # (b)ase (n)ame
$gf_id = lambda { |x_it| File .directory? x_it } # (i)s (d)irectory
def gf_pn x_it, x_chedk_id = false; ( x_chedk_id and ( $gf_id .call x_it ) ) ? (x_it) : ( File .dirname x_it ); end # (p)ath (n)ame
$gf_pn = method :gf_pn
def gf_on x_it, x_chedk_id = false; $gf_bn .call $gf_pn .call x_it, x_chedk_id; end # f(o)lder (n)ame
$gf_on = method :gf_on

$GC_OLIM_PN = $gf_pn .call $GC_MILO_PN
$GC_OLIM_NM = $gf_on .call $GC_OLIM_PN, true

$GC_TONO_HM = $GC_MILO_PN
$GC_TONO_NM = $gf_on .call $GC_TONO_HM, true

$gf_sf = lambda { | * x_args | sprintf *x_args }

$GC_KAPA_HM = $gf_pj .call 'C:', 'ProgramData', 'Bichon Frise', 'Kapa'
$GC_JAVA_HM = $gf_pj .call 'C:', 'Program Files (x86)', 'Java', 'jdk1.8.0_66'
$GC_RUBY_HM = $gf_pj .call $GC_KAPA_HM, '19.11.01', 'Vindue', 'x32', 'ActiveScriptRuby', '1.8.7-p330'

ENV['JAVA_HOME'] = $GC_JAVA_HM

ENV['Path'] = [ ( $gf_pj .call $GC_RUBY_HM, 'bin' ), ENV['Path'] ] .join $GC_PASA

$GC_PYTHON_HM = $gf_pj .call $GC_KAPA_HM, '19.01.22', 'Vindue', 'x32', 'Anaconda', '2.3.0'
$GC_JEP_PN = $gf_pj .call $GC_PYTHON_HM, 'Lib', 'site-packages', 'jep'
$GC_JEP_JAR_FN = $gf_pj .call $GC_JEP_PN, 'jep-3.8.2.jar'
$GC_QT_PLUGIN_PATH = $gf_pj .call $GC_PYTHON_HM, 'Lib', 'site-packages', 'PyQt5', 'plugins'

ENV['Path'] = [ $GC_PYTHON_HM, ENV['Path'] ] .join $GC_PASA
ENV['PYTHONPATH'] = $gf_pj .call $GC_PYTHON_HM, 'Lib'

require 'iconv'
require 'rjb'

$GC_CONV_2_UTF8 = Iconv.new 'UTF-8//IGNORE', $GC_ENCODING
$GC_CONV_2_BACK = Iconv.new $GC_ENCODING, 'UTF-8//IGNORE'

def gf_2u x_it
if x_it .kind_of? Array
return x_it .map { |bx2_item| ( bx2_item .kind_of? String ) ? ( $GC_CONV_2_UTF8 .iconv bx2_item ) : bx2_item }
elsif x_it .kind_of? String
$GC_CONV_2_UTF8 .iconv x_it
else
x_it
end
end

def gf_2b x_it
if x_it .kind_of? Array
return x_it .map { |bx2_item| ( bx2_item .kind_of? String ) ? ( $GC_CONV_2_BACK .iconv bx2_item ) : bx2_item }
elsif x_it .kind_of? String
$GC_CONV_2_BACK .iconv x_it
else
x_it
end
end

lambda {
pu_jars = [
( $gf_pj .call $GC_KAPA_HM, '19.01.22', 'Cumuni', 'Groovy', '2.5.8', 'indy', 'groovy-2.5.8-indy.jar' ),
( $gf_pj .call $GC_KAPA_HM, '19.01.22', 'Cumuni', 'Groovy', '2.5.8', 'indy', 'groovy-jsr223-2.5.8-indy.jar' ),
$GC_JEP_JAR_FN,
] .join $GC_PASA
Rjb::load pu_jars, [ '-Dfile.encoding=UTF-8', "-Djava.library.path=#{$GC_JEP_PN}" ]
} .call

$ju_g = ( Rjb::import 'javax.script.ScriptEngineManager' ) .new .getEngineByName ('Groovy')
$jf_ge = lambda { |x_str| $ju_g .eval x_str } # ge = (g)roovy (e)val
$jf_gf = lambda { | x_nm, * x_args | $ju_g .invokeFunction x_nm.to_s, x_args } # gf = (g)roovy (f)unction

$jf_ge .call '''
gf_cls = { x_cls_nm -> Class .forName (x_cls_nm) } // find class from string
'''

$jf_cls = lambda { |x_cls_nm| $jf_gf .call 'gf_cls', x_cls_nm }

lambda {
pu_src_pn = $gf_pj .call $GC_MILO_PN, 'src', 'python'
$ju_t = ( Rjb::import 'jep.Jep' ).new false, pu_src_pn
$ju_t .set 'GC_QT_PLUGIN_PATH', $GC_QT_PLUGIN_PATH
$ju_t .runScript $gf_pj .call pu_src_pn, 'SToa.py'
} .call
$jf_tf = lambda { | x_nm, * x_args | $ju_t .invoke x_nm.to_s, x_args } # tf = py(t)hon (f)unction

$CjSystem = $jf_cls .call 'java.lang.System'
$CjString = $jf_cls .call 'java.lang.String'
$CjLong = $jf_cls .call 'java.lang.Long'

$jf_sf = lambda { | x_format, * x_args |
fu_r = $CjString .format x_format, ( gf_2u x_args )
gf_2b fu_r
}

#---------------------------------------------------------------
# Your Source
#---------------------------------------------------------------

$jf_ge .call '''
sf_hello = { x_str, x_no -> "Hello ${ x_str * x_no } !!!" }
sf_sum = { long ... x_args -> x_args*.value .sum () }
'''
$sf_g_hello = lambda { | x_str, x_no | gf_2b $CjString .valueOf $jf_gf .call 'sf_hello', ( gf_2u x_str ), x_no }
$sf_g_sum = lambda { | * x_args | ( $jf_gf .call 'sf_sum', *x_args ) .longValue }

$sf_t_hello = lambda { | x_str, x_no | gf_2b $CjString .valueOf $jf_tf .call 'sf_hello', ( gf_2u x_str ), x_no }
$sf_t_sum = lambda { | * x_args | ( $jf_tf .call 'sf_sum', *x_args ) .longValue }

$sf_n_format = lambda { | x_format, * x_args |
fu_args = gf_2u x_args
gf_2b $CjString .valueOf $jf_tf .call 'sf_n_format', x_format, *fu_args
}

0 comments on commit 0a97f77

Please sign in to comment.