Python & tcc 学習:libtcc 直接使用

2017-05-24 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-19)の記事「tcc 学習:libtcc 直接使用(成功)」では、

  ・・・・・
  ・・・・・
  つまり、
  カレントには、(正しい?)use_libtcc_inline_C.gsl ダケで十分。

  結局、以下のコードで十分:
  ・・・・・
  ・・・・・

と云うことで、
libtcc.dll”を直に使うだけで、
所謂インラインCコードが使えた。


なので、
今回は Python での“libtcc 直接使用”に挑戦。


先日の“use_libtcc_inline_C.gsl”の移植と云うこと?

出来たコードは:
# -*- coding: utf-8 -*-
# ---------- use_libtcc.py -----
import ctypes as ct
tcc = ct.CDLL( 'libtcc' )

ST=''' int Add( int x, int y ){
return x + y;
}
'''
relocate_auto = ct.c_void_p(1)

TCL = tcc.tcc_new();
z = tcc.tcc_set_output_type( TCL, 0 );

z = tcc.tcc_compile_string( TCL, ST );
tcc.tcc_relocate( TCL, relocate_auto )

Add_proto = ct.CFUNCTYPE( ct.c_int, ct.c_int, ct.c_int )
Add = Add_proto( tcc.tcc_get_symbol( TCL, 'Add' ) )
# ------------------

z = Add( 2, 5 )
print( z )

# ------------------
tcc.tcc_delete(TCL)
_=raw_input()
これ1本でOK。

コーディング量は Lua に比べて少ない!


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170408
スポンサーサイト

LuaJIT-tcc 学習:これって、コールバック処理?

2017-05-22 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-20)の記事「LuaJIT-tcc 学習:利用法まとめ」で、
  ・・・・・
  ・・・・・
  即ち、Cコードで、SUB 関数を定義し、即時に実行する。
  この時、SUB 関数は、
  ・・・・・
  ・・・・・
  パターンB:Lua の 自作 BBB 関数を呼ぶ
  ・・・・・
  ・・・・・
と書いているが、・・・・・

これって、所謂コールバック処理でしょうか?


まあ、それは置いておいて、
今回、データの共有が出来るのか?
確認してみた。

テスト・プログラムはつまらないもの:
メイン処理で作ったテーブルを(上記の)関数でアクセスできるか?
----- L_C_L_global.gsl
tcc = require 'tcc' ( 'libtcc' )
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
-------------------- 以上は、固定

function Lget(n) return tbl[n] end

-------------------
TCL:add_symbol( 'Lget', Lget, 'double(*)(int)' )

TCL:compile_string [[
double Lget( int );
double Cget( int n ){ return Lget( n ); }
]]
TCL:relocate( 'relocate_auto' )

Cget = TCL:get_symbol( 'Cget', 'double(*)(int)' )
-------------------

tbl = ffi.new( 'double[5]', 0.1, 1.2, 2.3, 3.4, 4.5 )
z = Cget(3) -- Lua から、C を呼ぶ。その C は、Lua を呼ぶ。
-- 「tbl」共有可能か?確認
print( z )
-------------------- 以下は、固定
TCL:delete()
これを実行すると。
結果は 3.4 となる。
これは正解ですネ。


つまり、グローバルデータは使える。

当然のことでしたか?


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170407

LuaJIT-tcc 学習:利用法まとめ

2017-05-20 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-13)の記事「LuaJIT-tcc:例題から学習」で、
幾つかのパターンについて学習したが、
その後の学習結果を含め、“tcc.lua”の利用パターンをまとめた。


最初に、'tcc.lua' モジュールを解読(?)した結果から、・・・・・

'libtcc.dll' の内部にある関数は以下の19個か?
TCCState* tcc_new( void );
void tcc_delete( TCCState* s );
void tcc_set_lib_path( TCCState* s, const char* path );
void tcc_set_error_func( TCCState* s, void* error_opaque, void ( *error_func )( void* opaque, const char* msg ) );
int tcc_set_options( TCCState* s, const char* str );
int tcc_add_include_path( TCCState* s, const char* pathname );
int tcc_add_sysinclude_path( TCCState* s, const char* pathname );
void tcc_define_symbol( TCCState* s, const char* sym, const char* value );
void tcc_undefine_symbol( TCCState* s, const char* sym );
int tcc_add_file( TCCState* s, const char* filename );
int tcc_compile_string( TCCState* s, const char* buf );
int tcc_set_output_type( TCCState* s, int output_type );
int tcc_add_library_path( TCCState* s, const char* pathname );
int tcc_add_library( TCCState* s, const char* libraryname );
int tcc_add_symbol( TCCState* s, const char* name, const void* val );
int tcc_output_file( TCCState* s, const char* filename );
int tcc_run( TCCState* s, int argc, char* *argv );
int tcc_relocate( TCCState* s1, void* ptr );
void* tcc_get_symbol( TCCState* s, const char* name );
これに対して、
'tcc.lua' が公開している関数は19個で、
大半(以下の14)は右から左:
TCCState* tcc_new()
void tcc_delete( s )
void tcc_set_lib_path( s, path )
void tcc_set_error_func( s, opaque, error_func )
int tcc_set_options( s, str )
int tcc_add_include_path( s, pathname )
int tcc_add_sysinclude_path( s, pathname )
void tcc_define_symbol( s, sym, value )
void tcc_undefine_symbol( s, sym )
int tcc_add_file( s, filename )
int tcc_compile_string( s, buf )
int tcc_add_library_path( s, pathname )
int tcc_add_library( s, libraryname )
int tcc_output_file( s, filename )
だが、
以下の5つでは若干の処理を行っている。
set_output_type( s, type )         -- 第2引数は、変換している
relocate( s, ptr ) -- 第2引数は、変換している
add_symbol( s, name, val, ctype ) -- 第3、4引数で処理をしている
get_symbol( s, name, ctype ) -- 第3引数で処理をしている
run( s, t ) -- 第2引数で処理をしている
'libtcc.dll' 直接使用では、
追加の処理が必要。

それで、 <紙>が欲しいのは以下の9個かナ?
TCCState* tcc_new( void );
void tcc_delete( TCCState* s );
int tcc_set_output_type( TCCState* s, int output_type );
int tcc_add_file( TCCState* s, const char* filename );
int tcc_add_symbol( TCCState* s, const char* name, const void* val );
int tcc_compile_string( TCCState* s, const char* buf );
int tcc_relocate( TCCState* s1, void* ptr );
int tcc_output_file( TCCState* s, const char* filename );
void* tcc_get_symbol( TCCState* s, const char* name );
以上を使ったもののまとめ。


初めに、単に DLL ファイルを作るパターンについて、・・・・・
これは、
先日の記事の(2)DLL ファイル( 'k_lib.dll' )を作るパターン

“Add”関数1つを定義した“k_lib.dll”を作る場合:
-------- make_dll.gsl -----------
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_dll' )

-- ===== Cコード ===============
TCL:compile_string[[
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int Add( int x, int y ){
return x + y;
}
]]
TCL:output_file( 'k_lib.dll' )
TCL:delete()
とする。


次に、Cコードをコンパイルして即時に実行するパターン

当面考えられる全てのパターンを集めた場合を考える。

即ち、Cコードで、SUB 関数を定義し、即時に実行する。

この時、SUB 関数は、
パターンA:C の AAA 関数を呼ぶ
パターンX:Lua の 標準関数(例:math.sin)を呼ぶ
パターンB:Lua の 自作 BBB 関数を呼ぶ
パターンC:既存DLL にある CCC 関数を呼ぶ
これらのパターンを含めるとすると、
----- 以下2行は必須。
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
----------

-- function BBB( x ) return ~ end -- 関数定義 -- パターンB の場合

TCL:set_output_type( 'output_memory' )

-- TCL:add_file( 'k_lib.dll' ) 既存 DLL ファイル -- パターンC の場合

-- TCL:add_symbol( 'BBB', BBB, 'int(*)( int, int )' ) -- パターンB の場合

-- TCL:add_symbol( 'sin', math.sin, 'double(*)(double)' ) -- パターンX の場合

TCL:compile_string [[

// -- double sin( double ) -- プロトタイプ宣言 -- パターンX の場合

// -- ここに、CCC 関数 のプロトタイプ宣言 -- パターンC の場合

// -- ここに、AAA 関数定義の Cコード -- パターンA の場合

double SUB( double x, double y ){ // SUB 関数のコード

double z;

// 各パターン( A, X, B, C ) の関数を利用するCコード

return z;
}
]]

TCL:relocate( 'relocate_auto' )
SUB = TCL:get_symbol( 'SUB', 'double(*)( double, double )' )

----- ここで、SUB を使う LuaJIT のコード

以上。
些か分かりにくいかナ?



ここで、パターンC の場合 に、
add_file 関数で指定するファイル名は、
既存の DLL ファイルの方が良かった。
つまり、
以前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」の様に、
def ファイルを指定すると、
両方のファイルが必要となってしまう。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170406,19

tcc 学習:libtcc 直接使用(成功)

2017-05-19 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-17)の記事「tcc 学習:libtcc 直接使用」では、

  libtcc1.a に関するエラー原因不明。

で終わっていた。


その後の学習で、原因が判明した。


一番大事なことは、

tcc への PATH を登録している場合、
カレントに、libtcc.dll を置いてはダメ。


と云うことでした。


カレントに置かなければ、libtcc1.a を見つける。
なので、libtcc1.a もカレントに置かなくて良い。
(置いても問題ないが、それはムダ)


そうすると、

  tcc_add_library_path( TCL, '.' )

の行もイラナイ。


つまり、
カレントには、(正しい?)use_libtcc_inline_C.gsl ダケで十分。


結局、以下のコードで十分:
----- use_libtcc_inline_C.gsl -----
-------- void* は、正確には TCCState*
ffi.cdef[[
void* tcc_new( void );
int tcc_set_output_type( void* s, int output_type );

int tcc_compile_string( void* s, const char* buf );
int tcc_relocate( void* s1, void* ptr );

void* tcc_get_symbol( void* s, const char* name );
void tcc_delete( void* s );
]]

-- =========================
tcc = ffi.load( 'libtcc' ) -- カレントに libtcc.dll は置かない
relocate_auto = ffi.cast( 'void*', 1 )

charA = |s| ffi.cast( 'char*', s )
-- =========================

TCL = tcc.tcc_new()
tcc.tcc_set_output_type( TCL, 0 ) -- 0 : run in memory

-- ===== Cコード =====
sss = [[ int Add( int x, int y ){
return x + y;
}
]]
tcc.tcc_compile_string( TCL, charA(sss) )

tcc.tcc_relocate( TCL, relocate_auto )

sym = tcc.tcc_get_symbol( TCL, charA('Add') )
Add = ffi.cast( 'int(*)( int, int )', sym )

-- ===== GSL Shell コード =====

z = Add( 2, 5 ); print( z )
print( Add( 10, 5 ) )

-- ===== 後処理 ============
tcc.tcc_delete(TCL)
_=io.read(1)
こんな感じ。

これでスッキリした。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170406

tcc 学習:libtcc 直接使用

2017-05-17 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-05-12)の記事:
luajit-tcc:Tiny C Compiler 0.9.26 binding for LuaJIT」では、

  ・・・・・
  ・・・・・
  これって、
  以前(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた、
  “libtcc”を使ったもの?
  ・・・・・
  ・・・・・
  案の定「tcc.lua」1つあれば使える。
  ・・・・・
  ・・・・・

と云うことで、
libtcc”はイラナイのだが、・・・・・

tcc.luaモジュールを学習して、
libtccを直接使ってみることに挑戦。


tcc.luaモジュールの他に、
・ ~/tcc/libtcc/  にある、libtcc.h
と、
・ ~/tcc/examples/ にある、libtcc_test.c
も参照した。


それで、
以前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」で書いた、
“use_inline_C.gsl”を書き直した:
----- use_libtcc_inline_C.gsl -----
-------- void* は、正確には TCCState*
ffi.cdef[[
void* tcc_new( void );
int tcc_set_output_type( void* s, int output_type );
// #define TCC_OUTPUT_MEMORY 0 /* run in memory (default)
// #define TCC_OUTPUT_EXE 1 /* executable file
// #define TCC_OUTPUT_DLL 2 /* dynamic library
// ・・・・・・・・・・・・

int tcc_compile_string( void* s, const char* buf );
int tcc_relocate( void* s1, void* ptr );
// #define TCC_RELOCATE_AUTO (void*)1

void* tcc_get_symbol( void* s, const char* name );
void tcc_delete( void* s );
int tcc_add_library_path( void* s, const char* pathname );
]]

-- =========================
tcc = ffi.load( 'libtcc' ) -- カレントに libtcc.dll を配置
relocate_auto = ffi.cast( 'void*', 1 )

charA = |s| ffi.cast( 'char*', s )
-- =========================

TCL = tcc.tcc_new()
z = tcc.tcc_set_output_type( TCL, 0 )

-- ===== Cコード =====
sss = [[ int Add( int x, int y ){
return x + y;
}
]]
z = tcc.tcc_compile_string( TCL, charA(sss) )

-- この行が無いと、libtcc1.a が見つから無いエラー???
z = tcc.tcc_add_library_path( TCL, '.' ) -- カレントに libtcc1.a も配置

tcc.tcc_relocate( TCL, relocate_auto )

sym = tcc.tcc_get_symbol( TCL, charA('Add') )
Add = ffi.cast( 'int(*)( int, int )', sym )

-- ===== GSL Shell コード =====

z = Add( 2, 5 ); print( z )
print( Add( 10, 5 ) )

-- ===== 後処理 ============
tcc.tcc_delete(TCL)
_=io.read(1)
こんな感じかな。


libtcc1.a に関するエラー原因不明。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170405

tcc 学習:オブジェクト性能

2017-05-15 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-13)の記事「LuaJIT-tcc:例題から学習」に続いて、
今回は、tcc で生成したオブジェクトの性能について学習。


tcc プロセッサ自体の性能については、
先日(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた如く、

 ・FAST! tcc generates x86 code. No byte code overhead.
   Compile, assemble and link several times faster than GCC.
===
 ・早く! tccはx86コードを生成します。
   バイトコードオーバーヘッドはありません。 コンパイル、アセンブル、
   リンクはGCCより数倍高速です。

だそうですね。

そうすると、生成結果のプログラムの実行性能を知りたい。

例によって???
昨年9月(2016-09-23)の記事「LuaJIT vs LLVM/Clang」で書いた、
“フィボナッチ数を求めるプログラム”で実行時間を計測。

計測のためのプログラム:
----- fib.gsl ------
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
----------------------------
TCL:compile_string [[
int fib( int n ){
if( n < 2 ){ return n;
}else{ return fib(n-1) + fib(n-2);
}
}
]]
TCL:relocate( 'relocate_auto' )
fib = TCL:get_symbol( 'fib', 'int(*)( int )' )
-- ======================

local t=require'time'

Cst=t.time()
print( fib( 39 ) )
Cet=t.time()

print( Cet-Cst ) -- 0.515 秒

-- ====================
TCL:delete()
と云ったもの。

結果は、上記プログラム内コメントの通り。
これは、以前の LLVM/Clang での結果の -O3 無しに相当する。

つまり、
tcc のオブジェクトは、
最適化無し LLVM/Clang のオブジェクトと一緒。
LuaJIT に比べて、約 1.5 倍速い。


tcc は、MinGW に比べて、
コンパイル時間は数倍速く、オブジェクト性能は同等
(最適化機能は無し)
と云うこと?


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170404

LuaJIT-tcc:例題から学習

2017-05-13 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-12)の記事「luajit-tcc:Tiny C Compiler ・・・」で書いた、
同梱例題を基に、本格的(?)な学習を行った。

(1)例題の「base.lua」同様に、インラインCコードで関数を定義し、
  その場でそれを使う、GSL Shell プログラム:
  (追加でのファイル出力は無し)
-------- use_inline_C.gsl -----
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )

-- ===== Cコード ==========
TCL:compile_string [[
int Add( int x, int y ){
return x + y;
}
]]
TCL:relocate( 'relocate_auto' )
Add = TCL:get_symbol( 'Add', 'int(*)( int, int )' )

-- ===== GSL Shell コード =======
z = Add( 2, 5 ); print( z )

-- ===== 後処理 =====
TCL:delete()
_=io.read(1)
で、実行は、
「use_inline_C.gsl」ファイルのダブルクリックで可。


(2)例題の「compile_exe.lua」を流用して、
  DLL ファイル( 'k_lib.dll' )を作るもの:
-------- make_dll.gsl -----
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_dll' )

-- ===== Cコード =======
C_PG = [[
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int Add( int x, int y ){
return x + y;
}
]]
TCL:compile_string( C_PG )
TCL:output_file( 'k_lib.dll' )
TCL:delete()

-----------------------------
-- ===== 以下はテスト用 =====
klib = ffi.load( 'k_lib' )
ffi.cdef[[ int Add( int x, int y ); ]]

z = klib.Add( 2, 5 ); print( z )
_=io.read(1)
で、実行は、
「make_dll.gsl」ファイルのダブルクリックで可。
この時、同時に「k_lib.def」ファイルも出来る。


(3)例題の「add_symbol.lua」を流用して、
  DLL ファイル(例えば上記の'k_lib.dll')を使う Cコードの例:
-------- use_dll_inline_C.gsl ---
tcc = require'tcc' ('libtcc')
TCL = tcc.new()
TCL:set_output_type( 'output_memory' )
TCL:add_file( 'k_lib.def' ) -- DLL 情報

-- ===== Cコード ========
TCL:compile_string [[
int Add( int, int ); // DLL 内 関数プロトタイプ

int L_Add( int x, int y ){
return Add( x, y );
}
]]
TCL:relocate( 'relocate_auto' )
L_Add = TCL:get_symbol( 'L_Add', 'int(*)( int, int )' )

-- ===== GSL Shell コード =======
z = LAdd( 2, 5 ); print( z )

-- ===== 後処理 ==========
TCL:delete()
_=io.read(1)
で、実行は、
「use_dll_inline_C.gsl」ファイルのダブルクリックで可。
但し、'k_lib.def'、'k_lib.dll'も一緒に置いておく。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170402,03

luajit-tcc:Tiny C Compiler 0.9.26 binding for LuaJIT

2017-05-12 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
Lua 向けの ライブラリでは、
基本Lua 用と、LuaJIT(GSL Shell)用とで、互換性が無い?

このことは、昨年3月(2016-03-15)の記事:
GSL Shell 学習:LuaJIT で IupLua は …」で書いている。

そして、昨年2月(2016-02-10)の記事:
GSL Shell 学習:LFS モジュール」で書いた、
LFSモジュールは、“LuaJIT”用のもので“Lua”用は別にある。

また、昨年9月(2016-09-05)の記事:
afxLua - MS Windows API Library」で書いた、
afxLuaライブラリは、“LuaJIT”用のもの。


そこで、
「LuaJIT library」で検索していたら、・・・・・

GitHub - Playermet/luajit-iup: IUP binding for LuaJIT
を見つけた。

だが、昨年4月(2016-04-28)の記事:
GSL Shell 学習:“IUP.lua”モジュール自作」で書いた、
自作 'IUP.lua' モジュール と同等?なもの。
イラナイ?


と、・・・・・

1段上を見た:
GitHub - Playermet
すると、
  Pinned repositories
に、
  luajit-tcc
  Tiny C Compiler 0.9.26 binding for LuaJIT
がある。

  “examples”フォルダには、4本のプログラムがある。

で、実質“tcc.lua”モジュール1本???


  Start using
では、
-- Windows
local tcc = require 'tcc' ('libtcc')
local tcc = require 'tcc' ('../some/path/libtcc.dll')
とあり、
その下に10行ちょっとのExample code
が載っている。

これって、
以前(2017-05-03)の記事「tcc - Tiny C Compiler」で書いた、
libtcc”を使ったもの?


早速、(右の「Clone or download」ボタンから)
ダウンロードした。
 「luajit-tcc-master.zip」 2016-01-02 付 4.91KB

ここで ( これまで保留していた ) tcc へのパスを登録した。
<紙>の場合は、D:/TOOL/Euler/tcc/

そうすると、
案の定「tcc.lua」1つあれば使える。
この1本は、“GSL Shell”に登録した。
<紙>の場合は、D:/TOOL/Lua/gsl-shell/gsl-shell/

そして、
4つの例題を試した。
「base.lua」「compile_exe.lua」「run.lua」と
「add_symbol.lua」

起動(実行)は、どこか作業用ディレクトリで、
gsl-shell  base.lua
等々で。


これは面白い。

libtcc”を使って見ようと思っていたが、
より使い勝手の良い“luajit-tcc”を学習しよう。


本日はここまで。


luajit-tcc 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170402

tcc 学習:call_lua51_Gen モジュール作成

2017-05-10 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-08)の記事「tcc 学習:既存 DLL を呼び出す DLL の作成」に続いて、
tcc の学習。

今回は、call_Lua51 の作成に関して学習。


これまでの学習から、

(1)“tiny_impdef”コマンドで、
  「lua51.dll」から「lua51.def」を作る。


(2)call_Lua51_Gen モジュールを tcc コードで作る:
// ----- call_Lua51_Gen.c -----
#include <windows.h>
#define DLLExport __declspec ( dllexport )

// -- lua51.dll 内 関数

void* luaL_newstate( void );
void luaL_openlibs( void* L );

int luaL_loadfilex( void* L, const char* fname, const char* mode );
int lua_pcall( void* L, int nargs, int nresults, int msgh );

void lua_getfield( void* L, int i , const char* name );
void lua_pushlightuserdata( void* L, void* p );
char* lua_pushstring( void* L, const char* s );

char* lua_tolstring( void* L, int index, size_t* len );
void lua_settop( void* L, int m ); // m == -(n) - 1
void lua_close( void* L );

//----------------
void* L; int z; char* SV; char buf[1025];

DLLExport char* call_Lua( char* PG, char* FN, void* IT, char* ST ){

L = luaL_newstate();
luaL_openlibs( L );

z = luaL_loadfilex( L, PG, "bt" );
z = lua_pcall( L, 0, 0, 0 ); // 1度実行

lua_getfield( L, -10002, FN );
lua_pushlightuserdata( L, IT );
lua_pushstring( L, ST );

lua_pcall( L, 2, 1, 0 ); // 引数 2 個, 戻り値 1 個

SV = lua_tolstring( L, -1, &z ); // 戻り値
strcpy( buf, SV );

lua_settop( L, -2 ); // lua_pop(L,1); 戻り値を pop
lua_close( L );

return buf;

}
これに対して、
tcc  -shared  call_Lua51_Gen.c  lua51.def
コマンドで、「call_Lua51_Gen.dll」を生成。


(3)今作った call_Lua51_Gen を使うメインプログラムを作る:
今回は、取り敢えず“GSL Shell”を使った。
----- call_call_Lua51_Gen_dll.gsl -----
lua = ffi.load( 'call_Lua51_Gen' ) -- call_Lua51 モジュール
ffi.cdef[[
char* call_Lua( char* PG, char* FN, void* IT, char* ST );
]]
charA = |s| ffi.cast( 'char*', s )
Int32 = |s| ffi.cast( 'int32_t', s )
voidA = |s| ffi.cast( 'void*', s ); NULL=voidA(0)

function printf( f, s, ... )
f = f or io.stdout
f:write(s:format(...))
end
-- 以下 Lua5.1 で実行するコード:( 'Lua51_Gen.lua'(下記)必要
-------------------------- 「lfs.dll」「time.lua」も必要
ss1=[[ print('Lua5.1---')
ffi.cdef[[ int rand(void);
double sqrt(double); ]]
ss2=[[
print( ffi.C.rand() ) -- 乱数生成
print( ffi.C.sqrt(3.0) ) -- 平方根算出
print( math.sin(1.0) )
require'lfs'; print( lfs.currentdir() )
t=require'time'; print(t.time())
print(IT[2])
DT=DblA(IT[5]); print(DT[3])
IT[0]=999; SV='ok!'
]]
ST=ss1..']]'..ss2 -- 上記2つの文字列結合 -----

---------------------- インタフェースデータ:
DT=ffi.new('double[5]', 1.1, 2.2, 3.3, 4.4, 5.5 )
IT=ffi.new('int32_t[6]',1,2,3,4,5,0)
IT[5]=Int32(voidA(DT))
-----------------------------------------

SV = lua.call_Lua(charA('Lua51_Gen.lua'),charA('Exec'),voidA(IT),charA(ST))
----------------------------- 中で実行!!!
-----------------------------------------
print( ffi.string(SV) ) -- 戻り値:文字列
print( IT[0] ) ----------- Lua5.1 実行結果
これで行ける。

実行には、
先月(2017-04-17)の記事「call_Lua 似非モジュール:Lua51 汎用・決定版
で作った「Lua51_Gen.lua」も必要。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170330

tcc 学習:既存 DLL を呼び出す DLL の作成

2017-05-08 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-06)の記事「tcc 学習:lua52.dll 利用その他」に続いて、
dll の利用に関して学習。

今回は、既存 DLL を呼び出す DLL の作成に関して学習。

先日(2017-05-05)の記事「tcc 学習:同梱例題その他」で書いた、
既存の“test_dll.dll”から始める。

(1)“tiny_impdef test_dll.dll”コマンドで
  「test_dll.def」を作る

(2)「test_dll.dll」を使う「use_k_dll.c」を作る:
// ----- use_k_dll.c -----
#include <windows.h>
#define DLLExport __declspec ( dllexport )

int Add( int x, int y ); // これは、'test_dll.dll' 内の関数

DLLExport int add2( int x, int y ){
int z = Add( x, y );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 2*z;
}

(3)“tcc -shared use_k_dll.c test_dll.def”コマンドで、
  「use_k_dll.dll」を作る
  「use_k_dll.def」も出来る

(4)「use_k_dll.dll」を使う「Main_use_k_dll.c」を作る:
// ----- Main_use_k_dll.c -----
int add2( int x, int y ); // これは、'use_k_dll.dll' 内の関数

int main(){
int z = add2( 2, 5 );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 0;
}

(5)“tcc Main_use_k_dll.c use_k_dll.def”コマンドで、
  「Main_use_k_dlls.exe」を作る

※※「Main_use_k_dll.exe」の実行には、2つの dll が必要。


更に、
メインプログラムを GSL Shellで作ってみる:
----- Main_use_k_dll.gsl -----
libK = ffi.load('use_k_dll') -- dll 読み込み
---------- 中で、test_dll.dll の Add を呼んでいる

ffi.cdef[[
int add2( int x, int y ); // use_k_dll 内の関数宣言
]]

----------------------------------------------

print( libK.add2( 2, 5 ) ) --- 出来る
の様に、
これまで通りに作れる。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170330

tcc 学習:lua52.dll 利用その他

2017-05-06 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-05)の記事「tcc 学習:同梱例題その他」に続いて、
dll の利用に関して学習。

前回の
  (4)MinGW で作った自作DLL“test_dll.dll”の利用は?
では、
  “DLL”ファイルから“DEF”ファイルを作る。
と書いた。

そこで、
lua52.dllが使えるか?
に挑戦した。


学習した手順通り:
tiny_impdef  lua52.dll
で、“lua52.def”が出来た。

それで、利用コードの一部を書いてみた:
// ----- k0_call_Lua.c -----
int luaL_newstate( void );

int main(){
int L = luaL_newstate();

char buf[256];
sprintf( buf, "%d", L );
printf( buf );

return 0;
}
これで、
“k0_call_Lua.exe”を作る:
tcc  k0_call_Lua.c  lua52.def
そして、
実行。
確かに state L が出来ているようだ。


他に学習したこと:

システムの「kernel32」「user32」「msvcrt」等の“.def”ファイルは、
(<紙>の場合) D:/TOOL/Euler/tcc/lib/ にあった。


新規に、tcc で、DLL を自作する時は、
MinGW ( Relo2 ) で作るような、シンプルなものではダメ。
#include <windows.h>
#define DLLExport __declspec ( dllexport )
DLLExport int add2( int x, int y ){
// ----- 以下省略
}
の様にキッチリ宣言しておかないとダメ。
なお、
tcc  -shared  hoge.c
では、
“hoge.dll”と同時に“hoge.def”も生成される。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329

tcc 学習:同梱例題その他

2017-05-05 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-05-03)の記事「tcc - Tiny C Compiler」の後、
ドキュメントに従って、同梱の例題や自前のプログラムを作ってみた。


先ずは、doc フォルダにある「tcc-win32.txt」で学習。


(1)システム PATH に登録:

取り敢えずは DOS 窓内のみで、<紙>の場合は、

  set path=%path%;D:\TOOL\Euler\tcc


(2)同梱サンプルのコンパイル:

examples フォルダにある「fib.c」を作業場所に持ってきた:
#include <stdio.h>
int fib( n ){
if( n <= 2 ) return 1;
else return fib(n-1) + fib(n-2);
}
int main( int argc, char **argv ){
int n;
if( argc < 2 ){
printf("usage: fib n\n"
"Compute nth Fibonacci number\n");
return 1;
}
n = atoi( argv[1] );
printf( "fib(%d) = %d\n", n, fib(n) );
return 0;
}
見た目の変更を加えた。

これに対して、

  tcc fib.c

と打ち込むと、

  tcc.exe

が出来る。

後は普通に実行出来る。

ここで、1行目の #inclede 文は無くても行ける。


更に、
(3)「tcc-win32.txt」には、興味深い事が載っている:

  Using libtcc as JIT compiler in your program

これは、もっと学習が必要ダ。


次に、
3月(2017-03-11)の記事「SpiderMonkey/js-ctypes 学習」でも使っている、
(4)MinGW で作った自作DLL“test_dll.dll”の利用は?

(1) 最初に“test_dll.dll”から“test_dll.def”を作る。
tiny_impdef  test_dll.dll
これだけ。

(2) 利用コードを書く:
// ----- use_dll.c -----
int Add( int x, int y ); // test_dll.dll 内にある関数
int main(){
int z = Add( 2, 5 );

char buf[256];
sprintf( buf, "%d", z );
printf( buf );

return 0;
}
最低限?

そして、.exe を作る
tcc  use_dll.c  test_dll.def
これで、
“use_dll.exe”ができる。

この時、“test_dll.dll”が PATH の通った処にあれば、

“use_dll.exe”は正常に実行できる。


本日はここまで。


tcc ( Tiny C Compiler ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329

tcc - Tiny C Compiler

2017-05-03 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
昨年暮(2016-12-11)の記事「Euler(EMT)学習:続き」では、

  ・・・・・
  ・・・・・

  ・“tcc”が含まれている。 つまり、“Tiny C Compiler”
    どの程度のものなのかナ?

  ・・・・・
  ・・・・・

と書いていた。


探してみると、これが本家サイト

  [Note: I am no longer working on TCC.
    Check the mailing list to get up to date information.]
  (Feb 15, 2013) TCC version 0.9.26 is out thanks to Thomas Preud'homme.
  ・・・・・
  ・・・・・

これって、( Google 翻訳 )

  [注:私はもはやTCCで働いていません。
    最新の情報を入手するにはメーリングリストをチェックしてください。]
  (2013年2月15日)TCCバージョン0.9.26はThomas Preud'homme
  感謝しています。
  ・・・・・
  ・・・・・

ですか?(まあ、概要は分かる?)

つまりは、
最終バージョンは、0.9.26 ( H25-02-15 ) で、
もう開発はストップ。


それでも、そこそこ使えるのであれば使ってみたい


ホームページの
  Features ・・・ 特徴
には、

  ・SMALL! You can compile and execute C code everywhere,
    for example on rescue disks (about 100KB for x86 TCC executable,
    including C preprocessor, C compiler, assembler and linker).
  ・FAST! tcc generates x86 code. No byte code overhead.
    Compile, assemble and link several times faster than GCC.
  ・UNLIMITED! Any C dynamic library can be used directly.
    TCC is heading torward full ISOC99 compliance.
    TCC can of course compile itself.
  ・SAFE! tcc includes an optional memory and bound checker.
    Bound checked code can be mixed freely with standard code.
  ・Compile and execute C source directly.
    No linking or assembly necessary.
    Full C preprocessor and GNU-like assembler included.
  ・C script supported : just add '#!/usr/local/bin/tcc -run' at the first
    line of your C source, and execute it directly from the command line.
  ・With libtcc, you can use TCC as a backend for dynamic code generation.

===( Google 翻訳 )

  ・小さい! 例えばレスキューディスク(Cプリプロセッサ、Cコンパイラ、
    アセンブラ、リンカを含むx86 TCC実行可能ファイルの場合、約100KB)など、
    どこでもCコードをコンパイルして実行できます。
  ・早く! tccはx86コードを生成します。
    バイトコードオーバーヘッドはありません。 コンパイル、アセンブル、
    リンクはGCCより数倍高速です。
  ・無制限! 任意のC動的ライブラリを直接使用することができます。
    TCCはISOC99準拠の完全なtorgeを目指しています。
    TCCはもちろんコンパイルできます。
  ・安全! tccにはオプションのメモリとバウンドチェッカーが
    含まれています。
    結合されたチェックコードは、標準コードと自由に混在することができます。
  ・Cソースを直接コンパイルして実行します。
    リンクやアセンブリは必要ありません。
    完全なCプリプロセッサとGNUのようなアセンブラが含まれています。
  ・サポートされているCスクリプト:Cソースの最初の行に '・・・' を追加し、
    コマンドラインから直接実行します。
  ・libtccでは、TCCを動的コード生成のバックエンドとして使用できます。

とある。

・・・・・ 期待が持てる。


それで、
Euler 導入で一緒に入っていたものは、

バージョンは、0.9.26 と同じだが、タイムスタンプは、2013年11月13日。
幾つかのファイルの中身を比較してみたが、変わらない様ダ。

構成は、5つのフォルダと4つのファイルで、
ディスク上のサイズは、1.53MB
( doc と、examples フォルダを除くと 1.42MB とフロッピー 1枚分 )


すこし、学習してみよう。


本日はここまで。


tcc ( Tiny C Compiler ) 学習を始める。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329

見た目の前方参照(新方式):応用例

2017-05-01 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
先日(2017-04-12)の記事「GSL Shell 学習:見た目の前方参照?(新方式)」の
応用として、
先日(2017-04-05)の記事「GSL Shell 学習:Fitting サブ(改)」で書いた、
'SUB_GSL_Fit.lua' サブプログラムを、
それを利用するプログラムの後段に追加するようにしてみた。

---- GSL_Fit_init_After.gsl -----
F=io.open(arg[0]); w=F:read('*a'); F:close(); fnd=string.find
m='--ini'; _,k=fnd(w,m..'s',1,true); j=fnd(w,m..'e',k,true)
assert(load( string.sub(w,k+2,j-1) ))()
----------- 以下部分が本体 -----------
X = matrix.vec{ ・・・・・ }
Y = matrix.vec{ ・・・・・ }
------- Y ~ exp( -b * log(X) + c ) で近似
--------------------------------------
s = GSL_Fit( X, Y, 'b,c', 'exp(-b*log(x)+c)', '1,0', '-log(x)*exp(-b*log(x)+c)', 'exp(-b*log(x)+c)')
--------------------------------------
b, c = s.x[1], s.x[2] -- 求めた係数

----------- 以下初期化部分 -----------
os.exit(0) ----- これは必須
--inis
exp=math.exp; log=math.log
fmt = string.format
function GSL_Fit( x_, y_, k_, f_, p_, ... )
X__, Y__ = x_, y_ ----- これは local ではダメ
local pj = {...}
local n, jj = #x_, #pj
local st = 'function fdf( k, f, J )\n'
.. fmt( ' for i=1,%d do\n', n )

st = st .. fmt( ' local %s = k[1]', k_ )
for j=2,jj do st = st..fmt( ', k[%d]', j ) end
st = st .. '\n local x, y = X__[i], Y__[i]\n'
st = st .. fmt( ' if f then f[i] = ( %s - y ) end\n', f_ )
st = st .. ' if J then\n'
for j=1,jj do st=st..fmt( ' J:set( i, %d, %s )\n', j, pj[j] ) end
st = st .. 'end; end; end\n'
st = st .. fmt( 's_ = num.nlinfit{ n=%d, p=%d }\n', n,jj )
st = st .. fmt( 's_:set( fdf, matrix.vec{%s} )\n', p_ )

assert( load( st ) )() ----- function fdf 定義

for i=1, 100 do
s_:iterate()
if s_:test( 0, 1e-8 ) then break end
end
return s_
end
--inie
--- 以下は 自由領域:主にコメント用 ---

-- コメント

こんな感じ?

  assert( load( ~ ) )()

の2重(?)も可能ですネ。・・・当たり前?


本日はここまで。


Lua ( GSL Shell ) 学習は続く。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170323

JNR-FFI :ImageJ プラグイン(Java)では使えない?

2017-04-30 :  PCクリニック
Python、C言語、Perl、グルコサミン、Firefox
前(2017-04-29)の記事「Java:call_Lua51 似非モジュール」で書いた如く、
“jnr-ffi”を使えば、Java から LuaJIT を呼び出せた。


そもそも、
Java は、ImageJ のプラグイン作成用
としか(?)考えていない

そこで、
自作プラグイン・サンプルに、jnr-ffi を組み込んでみた。


昨年10月(2016-10-23)の記事「ImageJ 学習:プラグイン開発手順?」で作った:
「k_Java.java」をベースとした。

以下、太字部分を追加:
// ----- k_Java_FFI.java -----

import jnr.ffi.LibraryLoader; // 全4Dir必要

import ij.*;
import ij.gui.*;
import ij.plugin.PlugIn;
import ij.process.*;
import java.awt.*;

public class k_Java_FFI implements PlugIn{

public static interface libC { // これは適切に
int Add( int a, int b ); // 呼出関数のプロトタイプ
}

public void run( String arg ){
// =========================

ImagePlus imp1 = IJ.getImage(); // var → ImagePlus
ImageProcessor ip1 = imp1.getProcessor(); // var → ImageProcessor
int xx = ip1.getWidth(); // var → int
int yy = ip1.getHeight(); // 以下、var を適切に書き換え

libC klib = LibraryLoader.create(libC.class).load("_k_libs");
int zz = klib.Add( 10, 20 );


int x2=xx/2; int y2=yy/2;
ImagePlus imp2 = IJ.createImage( "out", "8-bit", x2, y2, 1 );
ImageProcessor ip2 = imp2.getProcessor();
imp2.show();

for( int y=0; y for( int x=0; x int v = (int)ip1.getf( x, y ); // cast も必須。
ip2.setf( x/2, y/2, zz );
}
}

imp2.updateAndDraw();

// =========================
}
}
以上の様なもの。

それから、
ImageJ インストール場所:D:/TOOL/ImageJ/ に、
4Dir と、「_k_libs.dll」を置き、

上記「k_Java_FFI.java」を
 D:/TOOL/ImageJ/plugins/_kami/ に置いた。



これで、ImageJでのコンパイルは正常?

しかし、実行してみると エラー
  java.lang.NoSuchMethodError: com.kenai.jffi.・・・
メソッドが見つからない???


この時の「Exception.txt」の内容は:
ImageJ 1.50i; Java 1.6.0_20 [32-bit]; Windows 7 6.1; 4295K of 640MB (<1%)

java.lang.NoSuchMethodError: com.kenai.jffi.CallContextCache.getCallContext(Lcom/kenai/jffi/Type;[Lcom/kenai/jffi/Type;Lcom/kenai/jffi/CallingConvention;Z)Lcom/kenai/jffi/CallContext;
at jnr.ffi.provider.jffi.InvokerUtil.getCallContext(InvokerUtil.java:205)
at jnr.ffi.provider.jffi.AsmLibraryLoader.generateInterfaceImpl(AsmLibraryLoader.java:127)
at jnr.ffi.provider.jffi.AsmLibraryLoader.loadLibrary(AsmLibraryLoader.java:59)
at jnr.ffi.provider.jffi.NativeLibraryLoader.loadLibrary(NativeLibraryLoader.java:43)
at jnr.ffi.LibraryLoader.load(LibraryLoader.java:287)
at jnr.ffi.LibraryLoader.load(LibraryLoader.java:266)
at k_Java_FFI.run(k_Java_FFI.java:25)
at ij.IJ.runUserPlugIn(IJ.java:216)
at ij.IJ.runUserPlugIn(IJ.java:229)
at ij.IJ.runPlugIn(IJ.java:180)
at ij.Executer.runCommand(Executer.java:137)
at ij.Executer.run(Executer.java:66)
at java.lang.Thread.run(Thread.java:619)
これでは、

JNR-FFI は、ImageJ プラグイン(Java)では使えない?

アキラメ?


本日はここまで。


見ていただいた序でとは厚かましい限りですが、
お帰りに投票して頂けるとなお嬉しいです。 ⇒ blogram投票ボタン


170329
おきてがみ/blogram
blogram投票ボタン



おきてがみ

最新記事
カレンダー
04 | 2017/05 | 06
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -
月別アーカイブ
カテゴリ
最新コメント
検索フォーム
リンク
プロフィール

<紙>

Author:<紙>
ようこそ。
「パソコンヲタクの雑記帳」
もろもろなことを綴っています。
パソコン ヲタクってねくら?
画像は kami でなく kani です。

カウンター(fc2、i2i) /Google Analytics


i2i(from 2010-08-24)
Total =
Today  =  
Yesterday=
アンチエイジング

Google Analytics
ブックマーク