我正在制作一个C++库的包装器,因此它可以在Java中使用,我正在使用Swig.
我面临的是我有一个Class SomeClass,它有一些重载的方法(someMethod).在这些重载方法中,有些接收复杂数据,我不想导出到包装器,还有一些我想要导出的简单数据.
我正在尝试使用该%rename("$ignore")指令,但要么我得到所有方法导出或没有.我有另一个两种类的SimpleData和ComplexData,在命名其中的一个ns1,另一个在ns2,SomeClass在命名空间"" ns3`.
班级SimpleData:
#ifndef SIMPLEDATA_H_
#define SIMPLEDATA_H_
namespace ns1 {
class SimpleData {
public:
SimpleData(){}
virtual ~SimpleData(){}
};
} /* namespace ns1 */
#endif /* SIMPLEDATA_H_ */
Run Code Online (Sandbox Code Playgroud)
ComplexData类:
#ifndef COMPLEXDATA_H_
#define COMPLEXDATA_H_
namespace ns2 {
class ComplexData {
public:
ComplexData(){}
virtual ~ComplexData(){}
};
} /* namespace ns2 */
#endif /* COMPLEXDATA_H_ */
Run Code Online (Sandbox Code Playgroud)
班级SomeClass:
#ifndef SOMECLASS_H_
#define SOMECLASS_H_
#include …Run Code Online (Sandbox Code Playgroud) 我有一个递归数据结构,基本上是一个树,其中一个节点可能有子节点,依此类推.我正在尝试生成该结构的类似JSON的文件.对于使用该#parse指令的想法.在上下文中,我存储根节点,在templateName中存储模板的名称.
{
"name" = "$node.name",
"value" = "$node.value"
#if ($node.childrens.size() > 0)
,
"childrens" = {
#foreach ($child in $node.childrens)
## The next statement does not work
#parse ($child.type + ".vm", $child)
#end
}
#end
}
Run Code Online (Sandbox Code Playgroud)
apache velocity文档声明该#parse指令只接受一个参数.
在示例中,我看到#set在调用另一个模板之前使用该指令,但是如果树的深度高于2,则这不起作用,因为#set指令中使用的变量存储在相同的上下文中,因此从深度1到2变量将被覆盖.
使用#parse@Sergiu Dumitriu建议的代替宏的原因是因为每个节点可能会以不同的方式呈现,具体取决于它的属性$node.type.我想为每种类型都有一个模板,所以一个人为特定类型添加模板不必混淆任何其他模板,我的意思是,也许这可以通过在type属性上切换来实现; 但这意味着所有渲染方式都将在同一个文件中定义.
有没有办法使用Velocity将模板应用于递归数据结构?
解决方案 根据Sergiu Dumitriu的答案,最终模板如下所示:
#macro ( displayNode $node)
{
#set ( $parseNode = $node )
#set ( $parseTemplate = $parseNode.type + ".vm" )
#parse …Run Code Online (Sandbox Code Playgroud) 我需要从linux终端查询MS SQL Server数据库.搜索网站和这个网站我找到了freetds,然后是sqsh.我已经安装了它们并且似乎连接到服务器但我无法让它执行查询,我肯定做错了什么.
我将freetds配置为:
[MSSql]
host = 192.168.1.4
port = 1433
tds version = 7.0
Run Code Online (Sandbox Code Playgroud)
数据库服务器是Sql Server 2008 r2.
连接时我使用以下命令:
sqsh -S MSSql -U sa -P sa -D databasename
Run Code Online (Sandbox Code Playgroud)
这给了我一个提示:
sqsh-2.1.7 Copyright (C) 1995-2001 Scott C. Gray
Portions Copyright (C) 2004-2010 Michael Peppler
This is free software with ABSOLUTELY NO WARRANTY
For more information type '\warranty'
1>
Run Code Online (Sandbox Code Playgroud)
然后我尝试输入如下查询:
1> select * from C_PROPS;
Run Code Online (Sandbox Code Playgroud)
但没有任何反应.我做错了什么?只需要简单的选择和更新.
当从C malloc保留内存时,应该如何使用c ++类?
我正在使用一个C库(lua),我需要向它公开一个C++类,在这种情况下,为了垃圾收集这些保留空间,lua进行内存预留.
下面是一个更简单的类似场景:
#include <string>
class Clase{
private:
std::string valor;
public:
Clase(){}
Clase(const std::string & valor) : valor(valor){}
const std::string & get() const { return this->valor; }
void set(const std::string & valor){ this->valor = valor;}
~Clase(){}
};
typedef struct
{
Clase cls;
}Estructura;
int main(int argc, char ** argv)
{
Estructura * est = (Estructura *) malloc(sizeof(Estructura));
est->cls.set("Hola"); // First attempt
Clase myCls; // Second attempt
est->cls = myCls;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我理解并检查过,使用malloc不会调用类构造函数; 这是预期的,因此无法使用无效实例(Class中的字符串)调用copy(assign)运算符.我怀疑在Class实例中复制字符串时,第二次尝试在同一点失败.
所以:
我需要用SWIG包装一个C++库,以便与Java一起使用它.
我已经有一些方法可以工作,但我遇到了一个我不知道如何解决它的情况.
我有几个像这样的方法:
void method1(std::string & name, std::string & result);
bool method2(std::string & name, std::string & alias, std::string & resurnValue, std::string & returnType);
Run Code Online (Sandbox Code Playgroud)
注意:实际上这是名为MyClass的类的成员方法.
我可以改变第一种方法来返回std::string而不是存在void,这应该有效; 但我不知道如何处理第二种方法,其中最后两个参数是输出参数.我已经看到了一些关于char *输出params 的问题(传递多个参数并使用Swig/Python在C中分配字符串),但在我的情况下应该是a std::string并且SWIG的文档没有提到这种情况在这里输入链接描述.此外,我可能会遇到更多返回3个或更多输出参数的方法,可能使用不同的类型.
最后我对接口有一点控制权,我也在开发一个充当库的入口点的类,但它只是将调用传递给真正的实现.
例如,通过这个我设法改变的方法一样method3(std::string & s)来method3(const std::string & s),所以我可以从Java与正常使用String.
所以修改一些方法签名是可能的,但如果一个本机方法返回n个输出参数,我应该返回所有这些(我不能创建新的方法来返回每个).
更新: 我一直在寻找Flexo给出的解决方案并且效果很好,但是我正在考虑做一个包装std :: string并使用它来与返回的字符串进行交互的类,这是一个非常类似于Flexo的第二个解决方案的方法,但使用此StringWrapper而不是使用java String数组,基本上如下所示:
/*
* The MyClass.i file
*/
%module example
%include "std_string.i"
%{
class StringPtr{
private:
stdString str;
public:
StringPtr(){
}
StringPtr(const stdString …Run Code Online (Sandbox Code Playgroud) 我在将lua日期转换为时间戳然后从中获取原始日期时遇到问题.它适用于非UTC日期,但不适用于UTC.
目前我的示例代码是:
local dt1 = os.date( "*t" );
print( dt1.hour );
local dt2 = os.date( "*t", os.time( dt1 ) );
print( dt2.hour );
print( "-=-=-" );
local dt1 = os.date( "!*t" );
print( dt1.hour );
local dt2 = os.date( "!*t", os.time( dt1 ) );
print( dt2.hour );
local dt2 = os.date( "*t", os.time( dt1 ) );
print( dt2.hour );
Run Code Online (Sandbox Code Playgroud)
产生输出:
12
12
-=-=-
10
9
11
Run Code Online (Sandbox Code Playgroud)
所以,在第二部分中,在获取时间戳后使用os.time( os.date( "!*t" ) ); 我不知道如何获得原始日期.我做错了什么?