我正试图进入嵌入在C++中的Common Lisp的迷人世界.我的问题是我无法从c ++中读取和打印由ECL中定义的lisp函数返回的字符串.
在C++中,我有这个函数来运行任意的Lisp表达式:
cl_object lisp(const std::string & call) {
return cl_safe_eval(c_string_to_object(call.c_str()), Cnil, Cnil);
}
Run Code Online (Sandbox Code Playgroud)
我可以用这种方式用数字来做:
ECL:
(defun return-a-number () 5.2)
Run Code Online (Sandbox Code Playgroud)
用C++读取和打印:
auto x = ecl_to_float(lisp("(return-a-number)"));
std::cout << "The number is " << x << std::endl;
Run Code Online (Sandbox Code Playgroud)
一切都设置好并且工作正常,但我不知道用字符串而不是数字来做.这是我尝试过的:
ECL:
(defun return-a-string () "Hello")
Run Code Online (Sandbox Code Playgroud)
C++:
cl_object y = lisp("(return-a-string)");
std::cout << "A string: " << y << std::endl;
Run Code Online (Sandbox Code Playgroud)
打印字符串的结果是这样的:
一个字符串:0x3188b00
我猜是字符串的地址.
这是捕获调试器和y cl_object 的内容.y-> string.self类型是一个ecl_character.
(从@ coredump的答案开始,该string.self字段提供结果.)
该string.self字段被定义为类型ecl_character*(ecl/object.h),它似乎在ecl/config.h中作为类型给出int(尽管我怀疑这是稍微依赖于平台的).因此,您将无法像打字符一样打印它.
我发现为我工作的方式是将其重新解释为wchar_t(即一个unicode角色).不幸的是,我有理由相信这不是可移植的,并且取决于ecl的配置方式和C++编译器.
// basic check that this should work
static_assert(sizeof(ecl_character)==sizeof(wchar_t),"sizes must be the same");
std::wcout << "A string: " << reinterpret_cast<wchar_t*>(y->string.self) << std::endl;
// prints hello, as required
// note the use of wcout
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用lisp类型base-string,它使用char(base-char在lisp中)作为其字符类型.然后读取lisp代码
(defun return-a-base-string ()
(coerce "Hello" 'base-string))
Run Code Online (Sandbox Code Playgroud)
(可能有更优雅的方式进行转换,base-string但我不知道它们).
用C++打印
cl_object y2 = lisp("(return-a-base-string)");
std::cout << "Another: " << y2->base_string.self << std::endl;
Run Code Online (Sandbox Code Playgroud)
(请注意,你不能混用wcout,并cout在同一程序)
| 归档时间: |
|
| 查看次数: |
611 次 |
| 最近记录: |