上一篇在這 C++混合編程之idlcpp教程Lua篇(7)
第一篇在這 C++混合編程之idlcpp教程(一)
與前面的工程相似,工程LuaTutorial6中,同樣加入了四個文件:LuaTutorial6.cpp, Tutorial6.cpp, Tutorial6.i, tutorial6.lua。其中LuaTutorial6.cpp的內容基本和LuaTutorial5.cpp雷同,不再贅述。
首先看一下Tutorial6.i的內容:
namespace tutorial
{
template<typename N>
struct Vector3
{
Vector3();
Vector3(const Vector3 ref v);
Vector3(N a, N b, N c);
Vector3(const N ptr p);
N getLength();
N length get;
N lengthSquare get;
static Vector3 s_zero;
meta:
N x;
N y;
N z;
N v[$3];
$*
union
{
struct
{
N x,y,z;
};
N v[3];
};
*$
};
template class Vector3<float>;
template class Vector3<double>;
typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d;
$*
template<typename N>
Vector3<N> Vector3<N>::s_zero(0, 0, 0);
template<typename N>
inline Vector3<N>::Vector3()
{
}
template<typename N>
inline Vector3<N>::Vector3(const Vector3<N>& v) : x(v.x), y(v.y), z(v.z)
{}
template<typename N>
inline Vector3<N>::Vector3(N a, N b, N c) : x(a), y(b), z(c)
{}
template<typename N>
inline Vector3<N>::Vector3(const N* p) : x(p[0]), y(p[1]), z(p[2])
{}
template<typename N>
inline N Vector3<N>::getLength()
{
return N(sqrt(x * x + y * y + z * z));
}
template<typename N>
inline N Vector3<N>::get_length()
{
return N(sqrt(x * x + y * y + z * z));
}
template<typename N>
inline N Vector3<N>::get_lengthSquare()
{
return (x * x + y * y + z * z);
}
*$
}
template<typename N>
struct Vector3
這是一個模板類,C++的模板功能復雜強大,編譯器實在難寫。所以大多數C++模板的高級特性在idlcpp中都沒有做支持,畢竟idlcpp只負責對腳本語言提供接口,有一些簡單的模板功能就夠用了,模板相關的語法和C++是一致的。
static Vector3 s_zero;
這一行聲明了一個靜態成員變量。idlcpp支持靜態成員變量,靜態成員函數,靜態屬性(實際上也是靜態成員函數)。
meta:
N x;
N y;
N z;
N v[$3];
$*
union
{
struct
{
N x,y,z;
};
N v[3];
};
*$
idlcpp 沒有提供 union。好在可以通過meta 和 $**$ 分別在生成的元數據描述代碼和C++頭文件提供各自的內容。
下面兩行代碼
template class Vector3<float>;
template class Vector3<double>;
和C++中模板類聲明一致。
idlcpp中通過這樣的聲明語句才會生成相應類型的元數據信息,這兩句對C++來說是可有可無的,但是對於idlcpp來說,想要讓腳本看見這兩個模板類實例類型,這兩行代碼是必須要寫的。
再下面兩行代碼
typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d;
為模板類實例類型聲明了類型別名。因為這兩個類型名分別是::tutorial::Vector3<float> 和 ::tutorial::Vector3<double>,在腳本中使用不方便,有了類型別名之後就可以通過::tutorial::Vector3f和::tutorial::Vector3d來使用。
後面就是成員函數的實現代碼,不在贅述。
編譯後生成的Tutorial6.h的內容如下:
//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org
#pragma once
#include "./Tutorial6.h"
namespace tutorial
{
template <typename N>
struct Vector3
{
public:
Vector3();
Vector3(const Vector3& v);
Vector3(N a,N b,N c);
Vector3(const N* p);
N getLength();
N get_length();
N get_lengthSquare();
static Vector3 s_zero;
public:
static Vector3* New();
static Vector3* New(N a,N b,N c);
static Vector3* New(const N* p);
static Vector3* NewArray(unsigned int count);
static Vector3* Clone(const Vector3& v);
union
{
struct
{
N x,y,z;
};
N v[3];
};
};
typedef Vector3<float> Vector3f;
typedef Vector3<double> Vector3d;
template<typename N>
Vector3<N> Vector3<N>::s_zero(0, 0, 0);
template<typename N>
inline Vector3<N>::Vector3()
{
}
template<typename N>
inline Vector3<N>::Vector3(const Vector3<N>& v) : x(v.x), y(v.y), z(v.z)
{}
template<typename N>
inline Vector3<N>::Vector3(N a, N b, N c) : x(a), y(b), z(c)
{}
template<typename N>
inline Vector3<N>::Vector3(const N* p) : x(p[0]), y(p[1]), z(p[2])
{}
template<typename N>
inline N Vector3<N>::getLength()
{
return N(sqrt(x * x + y * y + z * z));
}
template<typename N>
inline N Vector3<N>::get_length()
{
return N(sqrt(x * x + y * y + z * z));
}
template<typename N>
inline N Vector3<N>::get_lengthSquare()
{
return (x * x + y * y + z * z);
}
}
idlcpp會為只讀屬性length和lengthSquare 生成對應的函數聲明get_length和get_lengthSquare。idlcpp會根據構造函數聲明生成對應的靜態函數New,NewArray和Clone。
其他的內容,C++和idl基本上都是一樣的。
然後是Tutorial6.cpp
#include "Tutorial6.h" #include "Tutorial6.mh" #include "Tutorial6.ic" #include "Tutorial6.mc"
因為模板類的代碼都寫在頭文件中了,所以Tutorial6.cpp只需要包含對應的四個文件即可。
最後看一下Tutorial6.lua的內容
v1 = paf.tutorial.Vector3f(1,1,2); v1.z = 1; print(v1.length._); v2 = paf.tutorial.Vector3d(2,2,1); v2.v[2] = 2; print(v2:getLength()._);
編譯執行,結果如下圖:
