它是如何工作和编译C++;TCL的一个宏扩展,没有主功能 我有一个TCL脚本加C++扩展的工作集,但我不知道它是如何工作的以及它是如何编译的。我正在使用gcc和linux-Arch 它的工作原理如下:当我们执行Test.TCL脚本时,它会将一些值传递给一个定义为C++扩展的类的对象。使用这些值,使用宏的扩展将给出一些结果并打印一些图形
在test.tcl纸条中,我有:它是如何工作和编译C++;TCL的一个宏扩展,没有主功能 我有一个TCL脚本加C++扩展的工作集,但我不知道它是如何工作的以及它是如何编译的。我正在使用gcc和linux-Arch 它的工作原理如下:当我们执行Test.TCL脚本时,它会将一些值传递给一个定义为C++扩展的类的对象。使用这些值,使用宏的扩展将给出一些结果并打印一些图形,c++,macros,tcl,C++,Macros,Tcl,在test.tcl纸条中,我有: #!object use_namespace myClass proc simulate {} { uplevel #0 { set running 1 for {} {$running} { } { moveBugs draw .world.canvas .statusbar configure -text "t:[tstep]" } } } se
#!object
use_namespace myClass
proc simulate {} {
uplevel #0 {
set running 1
for {} {$running} { } {
moveBugs
draw .world.canvas
.statusbar configure -text "t:[tstep]"
}
}
}
set toroidal 1
set nx 100
set ny 100
set mv_dist 4
setup $nx $ny $mv_dist $toroidal
addBugs 100
# size of a grid cell in pixels
set scale 5
myClass.scale 5
object.cc看起来像:
#include //some includes here
MyClass myClass;
make_model(myClass); // --> this is a macro!
宏“make_model(myClass)”展开如下:
namespace myClass_ns { DEFINE_MYLIB_LIBRARY; int TCL_obj_myClass
(mylib::TCL_obj_init(myClass),TCL_obj(mylib::null_TCL_obj,
(std::string)"myClass",myClass),1); };
类别定义为:
class MyClass:
{
public:
int tstep; //timestep - updated each time moveBugs is called
int scale; //no. pixels used to represent bugs
void setup(TCL_args args) {
int nx=args, ny=args, moveDistance=args;
bool toroidal=args;
Space::setup(nx,ny,moveDistance,toroidal);
}
整个过程创建了一个细胞网格,其中一些点(虫子)从一个细胞移动到另一个细胞
我的问题是:
- 类方法和变量如何获取脚本值李>
- 如何有C++代码,没有主函数编译它?<李>
- 宏在扩展中做什么?它是如何工作的
谢谢每当运行Tcl中的命令时,它都会调用实现该命令的函数。该函数用C或C++语言编写,并在参数中传递(作为字符串或<代码> TCLUBOB**/COD>值)。完整扩展还包括一个函数,用于进行库初始化;函数(它是外部的,具有C链接,如果库是
Foo.dll
,它的名称类似于Foo_Init
)执行基本的设置任务,例如将实现函数注册为命令,它是显式的,因为它引用了正在初始化的解释器上下文
实现函数几乎可以做任何他们想做的事情,但要返回结果,它们使用函数之一Tcl\u SetResult
,Tcl\u SetObjResult
,等等。它们必须返回包含相关异常代码的int
。通常有用的是TCL\u OK
(无例外)和TCL\u ERROR
(用于出错)。这是一个C API,所以C++异常是不允许的。
<> P>可以使用C++实例方法作为命令实现,只要两者之间有绑定功能。特别是,函数必须通过抛出ClientData
值(实际上是void*
的别名,请记住这主要是一个C API)来获取实例指针,然后在该值上调用该方法。这只是少量的代码
编译只是构建一个链接到正确库(或库,根据需要)的DLL。虽然通常建议将扩展链接到存根库,但在一台机器上进行开发和测试时,不需要这样做。但是,如果您是针对Tcl DLL进行链接,那么最好确保将代码加载到使用该DLL的tclsh中。存根库摆脱了这种紧密的绑定,提供了相当强的ABI稳定性,但只需进行很少的设置工作;您需要定义正确的C宏来打开它们,并且需要在初始化函数中执行额外的API调用 我假设你已经知道如何编译和链接C++代码。我不会告诉你怎么做,但如果你需要帮助,这里肯定还有其他关于堆栈溢出的问题 使用代码?对于扩展,它基本上只是:
# Dynamically load the DLL and call the init function
load /path/to/your.dll
# Commands are all present, so use them
NewCommand 3
稍后还有一些额外的步骤可以将DLL转换为适当的Tcl包,将使用DLL的代码从事实上的DLL中抽象出来,等等,但在您的工作更加顺利之前,这些都不需要担心。@JoselitoS您的示例真的很难理解,因为它缺少很多细节。编辑你的问题,把信息放在那里。(这里的评论在你能写多少方面非常有限;它们是评论,而不是完整的讨论。)是的!但是你的回答确实帮助了我。我正在研究这个问题,几天后我会改进这个问题,让它对每个人都有用。我重新提出了这个问题,我希望现在能更好地理解它