首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c++11中将std::string转换为char *

在c++11中将std::string转换为char *
EN

Stack Overflow用户
提问于 2014-02-18 05:24:07
回答 4查看 5.4K关注 0票数 2

我正在为混合语言编写一个库,所以我们必须坚持C接口。我需要调用这个API函数:

代码语言:javascript
复制
void getproperty(const char * key, /* in  */ 
                 char * value      /* out */) {

我需要用std::的内容设置值。

代码语言:javascript
复制
std::string stdString = funcReturningString();
// set value to contents of stdString

我已经看到了很多关于可能的策略的答案,但是对于这个特定的用例,没有一个被认为是“最好的”或“标准”。我们正在使用C++11,因为它的价值。有些答案含糊地建议将字符串的内容复制到缓冲区中,并使用该缓冲区。但是怎么做呢?我希望在这次谈话中有更多的意见,这样我才能最终选择一个策略并坚持下去。

谢谢!

更新:下面是我使用的解决方案

我使用uint32_t来保持与其他API函数的一致性。bufferSize是一个引用,因为FORTRAN通过引用调用一切。

代码语言:javascript
复制
void getproperty(const char * key,            /* in  */ 
                 const uint32_t & bufferSize, /* in  */
                 char * value,                /* out */
                 uint32_t & error             /* out */) 
{
  std::string stdString = funcReturningString();

  if (bufferSize < str.size() + 1) {
    // Set the error code, set an error message, and return
  }

  strcpy(value, stdString.c_str());
}

我选择strcpy()来保持所有的标准,我选择了一个bufferSize参数,这样我就不必担心注释中提到的双重间接的一些问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-18 05:31:56

似乎getproperty API调用是有缺陷的。调用方无法说明value的长度。这意味着getproperty的实现不能安全地写入value,因为它不知道它有多长时间。getproperty方法需要更改为接受char** value或以value缓冲区的长度作为参数。让我们假设后者已经完成

代码语言:javascript
复制
void getproperty(const char* key, char* value, size_t valueLength);

现在,为了复制从funcReturningString返回的值的内容,我们只需要使用strncpy

代码语言:javascript
复制
std::string stdString = funcReturningString();
strlcpy(value, stdString.c_str(), valueLength);

注意,这仍然是有缺陷的。如果valueLength == 0或它小于字符串的长度,那么这是行不通的。最好将getproperty更改为还返回某种错误代码,这样就可以将这样的故障传递给调用方。

票数 10
EN

Stack Overflow用户

发布于 2014-02-18 05:36:49

一个简单的办法是:

代码语言:javascript
复制
strcpy(value, stdString.c_str());

但是,您需要小心缓冲区溢出。理想情况下,此函数的调用方还应该提供它所提供的缓冲区的大小,以确保您不会写过它的末尾。这样做的一种方法是传递额外的参数buffer_size并使用

代码语言:javascript
复制
strncpy(value, stdString.c_str(), buffer_size);
if (buffer_size > 0) value[buffer_size-1] = 0;

否则,在复制之前先缩短stdString。

票数 1
EN

Stack Overflow用户

发布于 2014-02-18 05:35:03

如果您需要得到可修改的值副本,您应该自己分配内存,value的类型也应该是指针到指针。

代码语言:javascript
复制
void getproperty(const char * key, /* in  */ 
                 char ** value     /* out */) {
  if (value == NULL) {
      // ERROR
      return;
  }

  const std::string& stdString = funcReturningString();

  // if this function is called from C 
  // you need to use 'malloc' instead of 'new' operator
  *value = malloc(stdString.size() + 1); // +NUL
  if (*value == NULL) {
      // ERROR mem alloc
      return;
  }

  memcpy(*value, stdString.c_str(), stdString.size() + 1); // +NUL
}

那么您应该这样称呼它(在C上):

代码语言:javascript
复制
char* value = NULL;
getproperty("key", &value);
// use
...
// free it
free(value);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21845034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档