|
楼主 |
发表于 2005-8-18 17:22:32
|
显示全部楼层
在你的程序中使用FinC
在本文中将配合wxFinC来讨论如何在程序中使用FinC,wxFinC是一个FinC的简单C++包装。
FinC以库的形式提供给程序使用,提供一套API来操作FinC解释器,例如执行一个FinC语言的脚本文件,执行包含FinC语言描述的字符串等等,除次之外,它也提供了如何和FinC内部进行交互,例如载入一套FinC脚本以后,调用API去执行一个FinC的函数,或者运行完一个FinC语言的函数后获得其中的变量值等等比较高级的操作。
首先,FinC的APIs,所用到的结构体都定义在finclib.h文件中。(当初设计时还算比较精妙,用C代码写成,却使用了OO的思想,所以代码可能会看起来稍微有些怪,Anyway,开始可以不用管FinC内部的实现代码)
在使用FinC解释器时,需要有一个FinC的环境,结构体struct _FinC描述了它,所以首先wxFinC需要有一个FinC的成员FinC* m_pFinC,即:
class wxFinC
{
private:
FinC* m_pFinC;
};
而使用时,m_pFinC必须由FinC解释器来分配(注意:FinC解释器中由严格的内存分配方式,不要试图操作FinC解释器中的内存对象)
wxFinC::wxFinC()
{
m_pFinC = finc_init();
}
而在不再使用FinC时,也就是退出,需要把分配的对象还回给FinC解释器。
wxFinC::~wxFinC()
{
finc_exit(m_pFinC);
}
OK,现在m_pFinC环境已经建立起来了,如何解释执行自己的FinC脚本呢?对wxFinC添加两个函数,RunScript,RunString,分别让FinC解释器解释执行FinC脚本文件,和包含FinC脚本的字符串。
int wxFinC::RunScript(wxString& filename)
{
finc_run_script(m_pFinC, filename.c_str());
return 0;
}
int wxFinC::RunString(wxString& str)
{
finc_run_string(m_pFinC, str.c_str());
return 0;
}
使用如上几种方法已经能够执行脚本程序了,但是只能使用语言的基本功能,如何直接和机器打交道呢?FinC允许直接向脚本环境注入API,使得FinC脚本能够直接调用本地的函数:
void finc_insert_func(FinC* self, unsigned char* p_name, void* p_func, unsigned char* p_rettype, ...);
那么有必要再添加方法:AddFunc
int wxFinC::AddFunc(wxString& func_name, void* func, wxString& return_type)
{
finc_insert_func(m_pFinC, func_name.c_str(), func, return_type.c_str());
return 0;
}
其中,
func_name是反应到FinC脚本里的名称,可以和实际的系统函数名无关。
func是系统函数指针。
return_type是系统函数的返回值。
那么函数的参数呢?由于FinC解释器对类型检查得并不严格,而是直接在调用时把所有的参数都传递给系统函数,所以函数参数可以省略掉。。。当然,代价就是,如果在执行FinC脚本时,调用系统函数参数错误将很可能导致程序崩溃。
还有什么?应该还有更多,欢迎你来补充。
完整的wxFinC代码:
/* -- file: wxfinc.h -- */
#ifndef __WX_FINC_H__
#define __WX_FINC_H__
#include "libfinc.h"
#include "wx/string.h"
class wxFinC
{
public:
wxFinC();
virtual ~wxFinC();
int RunScript(wxString& filename);
int RunString(wxString& str);
int AddFunc(wxString& funcname, void* func, wxString& return_type);
private:
FinC* m_pFinC;
};
#endif
/* -- file: wxfinc.cpp -- */
#include "wxfinc.h"
wxFinC::wxFinC()
{
m_pFinC = finc_init();
}
wxFinC::~wxFinC()
{
finc_exit(m_pFinC);
}
int wxFinC::RunScript(wxString& filename)
{
finc_run_script(m_pFinC, filename.c_str());
return 0;
}
int wxFinC::RunString(wxString& str)
{
finc_run_string(m_pFinC, str.c_str());
return 0;
}
int wxFinC::AddFunc(wxString& funcname, void* func, wxString& return_type)
{
finc_insert_func(m_pFinC, funcname.c_str(), func, return_type.c_str());
return 0;
} |
|