テーブルは常に参照型です(キリッ
数値は参照型ではありません。
文字列は参照型かもしれませんが文字列を直接編集する事はできないので特に意識する事は無いと思います。
2010年7月21日水曜日
2010年7月20日火曜日
C++プログラマがLuaを勉強してみる第13回
◆C/C++からLuaを呼び出すためのライブラリをコンパイルしてみる
さて、今回はLua5.1.4とVisual Studio 2008を使ってライブラリをコンパイルしてみます。 STEP 1:ソースをダウンロード
まずはここからソースをダウンロードして解凍します。STEP 2:Visual Studio 2008でプロジェクト作成
VC++でWin32プロジェクトを作成します。
次にアプリケーションの設定をスタティックライブラリに設定します。
完了します。
STEP 3:srcの取り込み
ダウンロードしたlua-5.1.4.tar.gzを解凍してsrcフォルダSTEP 2で作成したプロジェクトの有るフォルダにコピーします。
srcフォルダ内の.cファイルと.hファイルをプロジェクトに取り込みます。
このとき下記のファイルは必要有りません。
- lua.c
- luac.c
- print.c
STEP 4:プロジェクトの設定
プリプロセッサの定義に_CRT_SECURE_NO_DEPRECATEを追加します。えーっとプロジェクトの設定とかあまり詳しくないので過不足あったらすいません。
STEP 4:ビルド
2010年7月19日月曜日
C++プログラマがLuaを勉強してみる第12回
◆C/C++からLuaを実行する
C++からLuaのコードを実行するサンプルをつくりました。C++からLuaのコードを実行するためのライブラリ(lib)のコンパイルは後日紹介します。
extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
int main(int argc, char* argv[])
{
// LuaのVMを生成
lua_State *const L = lua_open();
// Luaの標準ライブラリを開く
luaL_openlibs(L);
while (true) {
// luaファイルを指定して実行する
if (luaL_dofile(L, "test.lua")) {
// エラー内容の取得
printf("error:%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return 0;
}
// 直接コードを指定する
if (luaL_dostring(L, "print('hello lua world')")) {
// エラー内容の取得
printf("error:%s\n", lua_tostring(L, -1));
lua_pop(L, 1);
return 0;
}
printf("\n");
printf("hit any key...\n");
printf("0 is exit\n");
const char c = getchar();
if (c == '0') {
break;
}
}
// LuaのVMを閉じる
lua_close(L);
return 0;
}
getchar()のところでtest.luaを編集ご実行すると編集内容が反映されます。
2010年7月10日土曜日
C++プログラマがLuaを勉強してみる第11回
◆コルーチンによるタイマスレッドみたいなの
を作ってみました。で、こんなの使うのだろうか。。。よくわかりませんw
isTimeout = false
--タイムアウトハンドラ
function timeOutHandler(_limit)
isTimeout = true
end
--タイマコルーチン用関数
function timer(_limit, callBack)
local limit = _limit --リミット
local startTime = os.time() --開始時間
local latest = os.time() --前回の時間
local countDown = _limit --カウントダウン用
print(countDown)
while true do
local time = os.time()
if startTime + limit <= os.time() then
break
elseif latest < time then
print(coroutine.status(co))
latest = time
countDown = countDown - 1
print(countDown)
end
coroutine.yield() --コルーチンを中断して処理をもどす
end
callBack(limit) --コールバック関数を呼ぶ
end
co = coroutine.create(timer) --コルーチンの生成
print(coroutine.status(co)) --ステータスの表示
--メインループ
repeat
coroutine.resume(co, 10, timeOutHandler) --コルーチンの開始と再開
until isTimeout
print(coroutine.status(co))
print("time out")
2010年7月9日金曜日
C++プログラマがLuaを勉強してみる第10回
◆Luaでテンプレートメソッドパターン
今回はLua初心者のくせにテンプレートメソッドパターンに挑戦してしまいました。テンプレートメソッドパターンについてはここ参照
無理矢理感が否めないので、ぜんぜんちっげーよ!ってコメント待ってます!
まずは、簡単にクラス図の説明を書きます。
なんかどっかでみたよーな命名ですが気にしない気にしない
CaffeineBeverageクラス(Superクラス)
△
|
----------------
| |
Coffeeクラス Teaクラス
以下ソースコード
CaffeineBeverage.lua
----------------------------------------
--CaffeineBeverageクラス
----------------------------------------
CaffeineBeverage = {}
-- new
function CaffeineBeverage:new(_caffeineBeverage)
local obj = {}
-- field
if _caffeineBeverage then
obj.name = _caffeineBeverage.name
else
obj.name = ""
end
self.__index = self
setmetatable(obj, self)
return obj
end
-- property
function CaffeineBeverage:set(_name)
self.name = _name
end
-- __tostring over ride
function CaffeineBeverage:__tostring()
return "name:"..self.name
end
-- clone
function CaffeineBeverage:clone()
return CaffeineBeverage:new(self)
end
-- prepareRecipe
function CaffeineBeverage:prepareRecipe()
CaffeineBeverage:boilWater()
CaffeineBeverage:brew()
CaffeineBeverage:pourInCup()
CaffeineBeverage:addCondiments()
end
-- boilWater
function CaffeineBeverage:boilWater()
print("お湯を沸かす。。。")
end
-- brew()
function CaffeineBeverage:brew()
error("have to override")
end
-- pourInCup
function CaffeineBeverage:pourInCup()
print("カップに注ぐ。。。")
end
-- addCondiments
function CaffeineBeverage:addCondiments()
error("have to override")
end
Coffee.lua
dofile("CaffeineBeverage.lua") -- C/C++で言うところの#include
----------------------------------------
--Coffeeクラス
----------------------------------------
Coffee = {}
-- new
function Coffee:new(_coffee)
obj = {}
-- field
if _coffee then
obj = CaffeineBeverage:new(_coffee)
else
obj = CaffeineBeverage:new()
end
-- clone (override)
obj.__index.brew = function()
return Coffee:new(self)
end
-- brew (overrice)
obj.__index.brew = function()
print("コーヒーをドリップする")
end
-- addCondiments (override)
obj.__index.addCondiments = function()
print("砂糖とクリープを加える")
end
return obj
end
Tea.lua
dofile("CaffeineBeverage.lua")
----------------------------------------
--Teaクラス
----------------------------------------
Tea = {}
-- new
function Tea:new(_tea)
obj = {}
-- field
if _tea then
obj = CaffeineBeverage:new(_tea)
else
obj = CaffeineBeverage:new()
end
-- clone
obj.__index.brew = function()
return Tea:new(self)
end
-- brew
obj.__index.brew = function()
print("ティーバッグをお湯に浸す")
end
-- addCondiments
obj.__index.addCondiments = function()
print("砂糖とレモン")
end
return obj
end
main.lua
dofile("Coffee.lua")
dofile("Tea.lua")
----------------------------------------
-- main
----------------------------------------
function main()
print("--コーヒーの生成")
a = Coffee:new()
a:set("コーヒー")
print(a)
a:prepareRecipe()
print("\n")
print("--紅茶の生成")
b = Tea:new()
b:set("紅茶")
print(b)
b:prepareRecipe()
print("\n")
print("--コピーコンストラクタの使用")
c = Tea:new(b)
print(c)
c:set("レモンティ")
print(c)
print(b)
print("\n")
print("クローン")
d = c:clone()
print(d)
d:set("レモンの紅茶")
print(d)
print(c)
end
-- call main
-- try catchみたいなの使ってます。
-- error()ってメソッドがthrowに相当します。
local status, err = pcall(main)
if status then
-- do nothing
else
print(err)
end
2010年7月8日木曜日
C++プログラマがLuaを勉強してみる第9回
◆関数定義時のピリオド「.」とコロン「:」の違い
コロンで定義した場合はselfが使用できますピリオドで定義した場合は引数にself(C++でいうところのthis)を取るとselfに自信が代入されます
test = {
name = "yamada"
}
-- コロン
function test:printName()
print(self.name) -- selfにtestが入っている
end
-- ピリオドでselfの引数をもつ
function test.printName2(self)
print(self.name) -- selfにtestが入っている
end
-- ピリオドでselfなし
function test.printName3()
-- print(self.name) -- selfは使用できない
print("yamada")
end
2010年7月7日水曜日
C++プログラマがLuaを勉強してみる第8回
◆クラス
---------------------------------------
--Characterクラスの定義
---------------------------------------
Character = {} --Characterクラス
--newメソッド
function Character:new(_character)
obj = {}
--メンバ変数の定義と初期化
if _character then
--コピーコンストラクタ的な処理
obj.name = _character.name
obj.age = _character.age
else
--デフォルトコンストラクタ適な処理
obj.name = ""
obj.age = 0
end
--Characterのメソッドをobjに設定
--継承みたいな感じ
self.__index = self
setmetatable(obj, self)
return obj
end
--setメソッド
function Character:set(_name, _age)
self.name = _name
self.age = _age
end
--__tostringメタメソッドのオーバーライド
function Character:__tostring()
return "name:"..self.name.."\n".."age:"..self.age
end
--cloneメソッド
function Character:clone()
return Character:new(self)
end
----------------------------------------
--クラスの使用
----------------------------------------
c = Character:new() --オブジェクトの生成
c:set("suzuki", 12) --データの設定
d = Character:new(c) --コピーコンストラクタの使用
print("--c--")
print(c)
print("--d--")
print(d)
print("\n")
c:set("suzuki_2", 24)
d:set("yamada", 55)
print("==c==")
print(c)
print("==d==")
print(d)
print("\n")
e = d:clone()
d:set("takeda", 77)
print("##d##")
print(d)
print("##e##")
print(e)
2010年7月6日火曜日
C++プログラマがLuaを勉強してみる第7回
◆関数
--基本
function f(_arg)
print(_arg)
end
f("Hello World")
f2 = function()
print("Hello World2")
end
f2()
--数の合わない引数
function fu(_arg1, _arg2)
print("_arg1:", _arg1)
print("_arg2:", _arg2)
end
fu("Hello")
fu("Hello", "World")
fu("Hello", "World", "Hi")
--可変長引数
function fun(...)
args = {...}
for index, value in ipairs(args) do
print(index, ":", value)
end
end
fun("Hello", "World")
2010年7月5日月曜日
C++プログラマがLuaを勉強してみる第6回
◆制御構文
fouループ
for i = 1, 10 do
print(i)
end
whileループ
while true do
str = io.read()
if str == "exit" then
break
else
print(str)
end
end
repeatループ
repeat
i = i + 1
print(i)
until 5 < i
if分岐
a = io.read()
if a == 1 then
a = a + 10
print(a)
elseif a == 2 then
a = a + 20
print(a)
else
print(a)
end
2010年7月3日土曜日
C++プログラマがLuaを勉強してみる第5回
◆連装配列
生成
t = {}t = {["name"] = "apple", ["class"] = "mage", ["job"] = "blacksmith"}
t = {name = "apple", class = "mage", job = "blacksmith"}
追加
t = {}t.name = "apple"
t.class = "mage"
t.job = "blacksmith"
削除
t.name = nil反復(なめる)
for key, value in pairs(t) doprint(value)
end
2010年7月2日金曜日
C++プログラマがLuaを勉強してみる第4回
◆配列
生成
t = {}
t = {"apple", "orange", "banana"}
追加
t[1] = "apple"
t[2] = "orange"
t[3] = "banana"
※Luaの添え字は「1」から始まります。
末尾に追加(push)
table.insert(t, "apple")
table.insert(t, "orange")
table.insert(t, "milk")
挿入
table.insert(t, 1, "apple")
table.insert(t, 2, "orange")
table.insert(t, 3, "orange")
削除
table.remove(t, index)
末尾から削除(pop)
table.remove(t)
サイズ(アイテム数)を取得する
#t
table.getn(t)
区切り文字で連結
table.concat(t) --> appleorangebananatable.concat(t, ",") --> apple,orange,banana
table.concat(t, ",", 2, 3) --> orange,banana
ソート
function s(_a, _b)
return _a < _b
end
table.sort(t, s)
反復(なめる)
t = { "apple", "orange", "banana"}
for index, value ipairs(t) do
print(value)
end
for i = 1, #t do
print(t[i])
end
2010年6月30日水曜日
C++プログラマがLuaを勉強してみる第3回
Luaのコメントは3種類あります
まずC++の//に相当する
-- コメント
続いて/**/に相当する
最初の「--」の後ろに任意の文字を入れるとコメント解除扱いとなります。
最後は内部にコメントを含めることが出来る
]=]
「=」の数は一つでなくともかまいませんが、開始と終了の数を等しくする必要があります。
まずC++の//に相当する
-- コメント
続いて/**/に相当する
--[
コメント--]
最初の「--」の後ろに任意の文字を入れるとコメント解除扱いとなります。
--![
コメント--]
最後は内部にコメントを含めることが出来る
--[=[
コメント ]=]
「=」の数は一つでなくともかまいませんが、開始と終了の数を等しくする必要があります。
C++プログラマがLuaを勉強してみる第2回
| 演算子 | 概要 | C++ |
|---|---|---|
| + | 加算 | + |
| - | 減算 | - |
| * | 積算 | * |
| / | 除算 | / |
| % | 剰余 | % |
| ^ | 累乗 | ^ |
| .. | 文字列連結 | +(STL) |
| and | 論理積 | && |
| or | 論理和 | || |
| not | 否定 | ! |
| < | 演算子の左より右が大きい | < |
| <= | 演算子の左より右が同じか大きい | <= |
| > | 演算子の左より右が小さい | > |
| >= | 演算子の左より右が同じか小さい | >= |
| == | 演算子の左と右が等しい | == |
| ~= | 演算子の左と右が異なる | != |
| # | 配列のサイズを求める | 該当演算子なし |
2010年6月29日火曜日
C++プログラマがLuaを勉強してみる第1回
予約語
and
論理積
C++:and、&&
例)A and B
break
for、whileなどのループを抜ける
C++:break
do
do~whileのdo とはちょっと違います。
do~endでブロックとなります。
C++:{}の{
else
if~elseのelse
C++:else
elseif
if~elseifのelseif
C++:elseif
end
ループの終了、ブロックの終了
C++:{}の}
例)for i = 0, 10 do hoge = hoge + i end
false
偽
C++:false
for
ループ
C++:for
function
関数
C++:関数ポインタみたいな感じ。名無しの関数を定義できる
if
条件式
C++:if
in
配列や連想配列を反復するのにつかう
C++:イテレータみたいなもの
例)
dict = { name = "snow", job="programer" }
for key, value in pairs(dict) do
print(key..":"..value);
end
ループやブロックの終端
C++:}
local
ローカル変数Luaでは基本グローバル変数なのでローカル変数としたい場合はlocalをつける
C++:なし
例)local hoge
nil
未定義
C++:NULLとは違う
not
否定
C++:!ビックリマーク
or
論理輪
C++:||、or
repeat
ループ
C++:なし
例)iが10になったらループを抜ける
repeat
i = i + 1
print(i)
until i == 10
return
復帰
C++:return
then
if文で使用する
C++:{}の{
例)
if a == 3 then
print(a)
end
true
真
C++:true
until
repeat文の条件式で成立したらループをぬける
C++:なし
例)iが10になったらループを抜ける
repeat
i = i + 1
print(i)
until i == 10
while
ループ
C++:while
| and | break | do | else | elseif |
| end | false | for | function | if |
| in | local | nil | not | or |
| repeat | return | then | true | until |
| while |
and
論理積
C++:and、&&
例)A and B
注:A and Bが真となるときBの値が返されます。
hoge = A and B
の場合、hogeにはBの値が代入されます。break
for、whileなどのループを抜ける
C++:break
do
do~whileのdo とはちょっと違います。
do~endでブロックとなります。
C++:{}の{
else
if~elseのelse
C++:else
elseif
if~elseifのelseif
C++:elseif
end
ループの終了、ブロックの終了
C++:{}の}
例)for i = 0, 10 do hoge = hoge + i end
false
偽
C++:false
for
ループ
C++:for
function
関数
C++:関数ポインタみたいな感じ。名無しの関数を定義できる
if
条件式
C++:if
in
配列や連想配列を反復するのにつかう
C++:イテレータみたいなもの
例)
dict = { name = "snow", job="programer" }
for key, value in pairs(dict) do
print(key..":"..value);
end
ループやブロックの終端
C++:}
local
ローカル変数Luaでは基本グローバル変数なのでローカル変数としたい場合はlocalをつける
C++:なし
例)local hoge
nil
未定義
C++:NULLとは違う
not
否定
C++:!ビックリマーク
or
論理輪
C++:||、or
注:A or BにおいてAが真となるときAの値が返されます。
hoge = A or B
でAがtrue又はnil以外の全ての値の場合、hogeにはAの値が代入されます。repeat
ループ
C++:なし
例)iが10になったらループを抜ける
repeat
i = i + 1
print(i)
until i == 10
return
復帰
C++:return
then
if文で使用する
C++:{}の{
例)
if a == 3 then
print(a)
end
true
真
C++:true
until
repeat文の条件式で成立したらループをぬける
C++:なし
例)iが10になったらループを抜ける
repeat
i = i + 1
print(i)
until i == 10
while
ループ
C++:while
登録:
コメント (Atom)



