我将lua嵌入到我的项目中,并遇到了strlen
和lua解释的奇怪(对我来说)行为。我试图加载一个包含lua代码的字符串luaL_loadbuffer
,并且它始终抛出" unexpected symbol
"在任何是lua代码的最后一行,除非整个块写在一行。例如:
function start()
print("start")
end
总会导致错误:第3行意外符号,但
function start() print("start") end
成功加载。
我发现用luaL_loadstring
加载相同的块没有错误,并且看到它使用strlen
来确定指定字符串的长度(我使用std::string::size
)和另外,使用strlen将字符串的长度提供给luaL_loadbuffer
也会导致成功加载。
现在的问题是:strlen和std :: string :: size之间可能有什么区别,最令我惊讶的是,strlen不计算新行(' \n
& #39)。那就是:
const char* str = "this is a string\nthis is a newline";
std::string str2(str);
str2.size(); // gives 34
strlen(str); // gives 33
大小和strlen返回的值之间的差异始终是新行字符的数量。
我的问题是:
我正在使用vs 2015和lua 5.3.0
修改
我的第一个例子并不准确,也没有为我产生详细效果,但我能够从原始代码中重新创建问题:
std::fstream _Stream("test.lua", std::ios::ate | std::ios::in);
std::string _Source;
if(_Stream.is_open()) {
_Source.resize(_Stream.tellg());
_Stream.seekg(0, std::ios::beg);
_Stream.read(&_Source[0], _Source.size());
_Stream.close();
}
std::cout << "std::string::size() = " << _Source.size() << std::endl;
std::cout << "strlen() = " << strlen(_Source.c_str()) << std::endl;
test.lua的内容为"function start()\n\tprint("start")\nend\n\nstart()"
区别在于换行符的数量:
答案 0 :(得分:1)
窗口的行结尾(CR + LF)是两个字符,使文件大小大于字符串中的字符数,因此 static void Main(string[] args)
{
var id = Guid.Parse("bleh");
Expression<Func<Thingemebob, bool>> selector = x => x.Id == id;
var tickList = new List<long>();
for (int i = 0; i < 100000; i++)
{
var sw = Stopwatch.StartNew();
GetValueWithExpressionsAndReflection(selector);
sw.Stop();
tickList.Add(sw.ElapsedTicks);
}
Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call included: " + tickList.Average());
Trace.WriteLine("GetValueWithExpressionsAndReflection: First call: " + tickList[0]);
Trace.WriteLine("GetValueWithExpressionsAndReflection: Average over 100000, first call excluded: " + tickList.Skip(1).Average());
tickList = new List<long>();
for (int i = 0; i < 100000; i++)
{
var sw = Stopwatch.StartNew();
GetValueWithCompiledExpression(selector);
sw.Stop();
tickList.Add(sw.ElapsedTicks);
}
Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call included: " + tickList.Average());
Trace.WriteLine("GetValueWithCompiledExpression: First call: " + tickList[0]);
Trace.WriteLine("GetValueWithCompiledExpression: Average over 100000, first call excluded: " + tickList.Skip(1).Average());
Debugger.Break();
}
private static void GetValueWithCompiledExpression(Expression<Func<Note, bool>> selector)
{
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
var o = Expression.Lambda(memberExpression).Compile().DynamicInvoke();
}
private static void GetValueWithExpressionsAndReflection(Expression<Func<Note, bool>> selector)
{
BinaryExpression binaryExpression = (BinaryExpression)selector.Body;
MemberExpression memberExpression = (MemberExpression)((UnaryExpression)binaryExpression.Right).Operand;
ConstantExpression constantExpression = (ConstantExpression)memberExpression.Expression;
FieldInfo member = (FieldInfo)memberExpression.Member;
var instance = constantExpression.Value;
var guid = member.GetValue(instance);
}
操作使用文件大小而不是以null结尾的字符串的长度。 resize
报告以null结尾的字符串的长度,并将strlen
计为单个字符。您可以通过调整字符串大小以匹配以后匹配C字符串的长度:
\n