C++ - 使用 uint8_t 指针将字符串值传递给函数

C++ - Passing string value to a function using uint8_t pointer

我正在学习 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;
  }
}

现在,对于像下面这样的简单添加函数,我了解了如何在设置 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 类型的指针?我试过下面的一个,但后来收到 "error: cannot convert std::string to uint8_t* in assignment"*

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);

那是因为您需要一个指向 c 字符串的指针,并且您提供了一个指向 std::string 的指针。 str.ptr = input.c_str() 应该适合你。

编辑: 但是,您似乎需要一个非常量指针。在这种情况下,您需要自己分配 input 变量,例如:

char input[128];

这将在堆栈上创建一个固定大小的数组。 但是您可能希望使用 new 动态分配它: char* input = new char[size];

另请查看 cstring header 中的函数,您可能需要使用这些函数。

您可能还需要如上所述将其转换为 uint8_t*

不要忘记在以后不再需要时 delete[] 字符串。但是既然你把它传递给了一个函数,这个函数应该可以处理这个。

字符串本身不是字符指针(这是你需要的),但你可以使用c_str函数得到一个。

str.ptr=(uint8_t*)(input.c_str ());

如果您想使用新式转换,您可能需要 const_cast(从 const char * 转换为 char *)和 reinterpret_cast,具体取决于 str.ptr 已定义。