我想知道是否存在从Common调用C++代码的方法(最好是可移植的,如果不是,最好在SBCL中调用,如果不是,那么可以使用Clozure、CLisp或ECL)。
C++将被调用到内部循环中进行数值计算,因此如果调用速度较快,那将是很好的选择。
CFFI似乎不支持这一点:
这个概念可以推广到其他语言;在编写本报告时,只有CFFI的C支持相当完整,但C++支持正在进行中。
(手册第4章)
SBCL的手册也没有提到C++,实际上它说
本章描述了SBCL与C程序和库的接口(而且,由于C接口是Unix世界的一种通用语言,一般也是其他程序和库的通用语言)。
C++代码使用OO和操作符重载,因此确实需要使用g++进行编译。
据我所知,我可以拥有一个C++ main()函数,并为C函数编写包装器,但情况并非如此--这是真的吗?
不管怎样..。有什么办法可以做到吗?
谢谢!
发布于 2009-09-05 11:51:14
哦,等等!
似乎有一个把戏我可以使用!
我用C++编写了一个包装器,声明包装函数的外部是"C":
#include "lib.h"
extern "C" int lib_operate (int i, double *x) {
...
}
可以从C和C++调用的头文件lib.h是:
#if __cplusplus
extern "C" {
#endif
int lib_operate (int i, double *x);
#if __cplusplus
}
#endif
然后用以下方法编译:
g++ -c lib.cpp
gcc -c prog.c
gcc lib.o prog.o -lstdc++ -o prog
似乎适用于玩具例子!:-)
因此,在通用Lisp中,我会在加载libstdc++之后调用包装器。
不管怎样,谢谢你的回答!
发布于 2009-09-05 05:25:34
编译后,大多数C++函数实际上归结为常规的C函数调用。由于函数重载和其他特性,C++编译器使用名称残缺来区分类似命名的函数。给定一个对象转储实用程序和关于C++编译器的足够知识,您可以直接从外部调用C++代码。
尽管如此,您可能会发现在Lisp和C++代码之间编写一个与C兼容的层会更容易。您可以像这样使用extern "C"
这样做:
extern "C" Foo *new_Foo(int x)
{
return new Foo(x);
}
这使得new_Foo()
函数遵循C调用约定,以便您可以从外部源调用它。
发布于 2009-09-05 05:59:05
除了名称mangling之外,调用C++函数而不是C函数的主要区别是“隐藏”特性,如这个指针,它们被隐式传递给成员函数。C运行时层对这些、隐式类型转换和其他有趣的C++特性一无所知,因此如果您打算通过C接口调用C++,则可能需要伪造这些特性。
假设您至少可以对要调用的对象及其所需的数据持有一个空*,则可以降级以下C++调用
matrix->multiply(avector);
如果您创建一个C包装函数,则调用C:
extern "C"
void matrix_multiply(void *cpp_matrix, void *cpp_vector) {
reinterpret_cast<matrix_type *>(cpp_matrix)->multiply(reinterpret_cast<vector_type *>(cpp_vector);
}
显然,函数matrix_multiply将位于C++源代码中并按此方式编译,但它确实向外界公开了一个C接口。只要您能够与不透明的指针交互,您就可以接受上面的翻译提示。
诚然,对于这样的问题,这不一定是最优雅的解决方案,但我过去曾在类似您的情况下使用过它。
另一种选择是直接进行C++调用,方法是将它们作为具有附加参数的C调用处理,并自己提供所有所需的信息,但这确实会使您很快地进入编译器特定代码的领域。基本上,您仍然持有指向C++对象的不透明指针,但您必须计算出要调用的函数的损坏名称。一旦得到了函数名,就必须提供这个指针(在C++中是隐式的,在上面的示例中是半隐式的)和正确的参数,然后调用函数。这是可以做到的,但正如前面提到的,它使您深入到编译器领域,甚至是编译器版本特定的行为领域。
https://stackoverflow.com/questions/1382529
复制相似问题