我正在学习C ++,以便创建一个我希望在Hadoop Cloudera Impala SQL中使用的自定义函数(用户定义函数是cloudera如何调用它)。 Cloudera提供了一个头文件,其中包含自定义函数参数的类型定义
struct AnyVal {
bool is_null;
AnyVal(bool is_null = false) : is_null(is_null) {}
};
//Integer Value
struct IntVal : public AnyVal {
int32_t val;
IntVal(int32_t val = 0) : val(val) { }
static IntVal null() {
IntVal result;
result.is_null = true;
return result;
}
}
//String Value
struct StringVal : public AnyVal {
static const int MAX_LENGTH = (1 << 30);
int len;
uint8_t* ptr;
/// Construct a StringVal from ptr/len. Note: this does not make a copy of ptr
/// so the buffer must exist as long as this StringVal does.
StringVal(uint8_t* ptr = NULL, int len = 0) : len(len), ptr(ptr) {
assert(len >= 0);
};
/// Construct a StringVal from NULL-terminated c-string. Note: this does not make a copy of ptr so the underlying string must exist as long as this StringVal does.
StringVal(const char* ptr) : len(strlen(ptr)), ptr((uint8_t*)ptr) {}
static StringVal null() {
StringVal sv;
sv.is_null = true;
return sv;
}
}
现在对于一个简单的Add函数,我知道如何在设置IntVal.val之后传递IntVal对象的引用并且它有效!
IntVal AddUdf(FunctionContext* context, const IntVal& arg1, const IntVal& arg2) {
if (arg1.is_null || arg2.is_null) return IntVal::null();
return IntVal(arg1.val + arg2.val);
}
int main() {
impala_udf::FunctionContext *FunctionContext_t ;
IntVal num1, num2 , res;
num1.val=10;
num2.val=20;
IntVal& num1_ref = num1;
IntVal& num2_ref = num2;
res = AddUdf(FunctionContext_t, num1_ref, num2_ref);
cout << "Addition Result = " << res.val << "\n";
}
但我不知道如何为字符串函数做类似的事情,因为StringVal要求我为字符串传递uint8_t类型的指针?我尝试了下面的一个,但接着 &#34;错误:无法将std :: string 转换为uint8_t *在作业中&#34; *
int main() {
impala_udf::FunctionContext *FunctionContext_t ;
StringVal str , res;
string input="Hello";
str.len=input.length();
str.ptr=&input;
StringVal& arg1=str;
res = StripVowels(FunctionContext_t, str);
cout << "Result = " << (char *) res.ptr<< "\n";
}
我也试过以下但没有快乐。任何指针在正确的方向将非常感激。感谢。
str.ptr=reinterpret_cast<uint8_t*>(&input);
答案 0 :(得分:0)
那是因为你需要一个指向c-string的指针,并且你提供了一个指向std::string
的指针。 str.ptr = input.c_str()
应该适合你。
编辑:
但是,似乎你需要一个非const指针。在这种情况下,您需要自己分配input
变量,例如:
char input[128];
这会在堆栈上创建一个固定大小的数组。
但您可能希望使用new动态分配它:
char* input = new char[size];
同时查看cstring header中的功能,您可能希望使用这些功能。
如上所述,您可能还需要将其投射到uint8_t*
。
以后当你不再需要它时,别忘了delete[]
字符串。但是既然你将它传递给一个函数,这个函数应该可以处理它。
答案 1 :(得分:0)
字符串本身不是字符指针(这是你需要的),但你可以使用c_str函数得到一个。
str.ptr=(uint8_t*)(input.c_str ());
如果你想使用新式的强制转换,你可能需要const_cast(从const char *转换为char *)和reinterpret_cast,具体取决于str.ptr的定义方式。