我正在为混合语言编写一个库,所以我们必须坚持C接口。我需要调用这个API函数:
void getproperty(const char * key, /* in */
char * value /* out */) {我需要用std::的内容设置值。
std::string stdString = funcReturningString();
// set value to contents of stdString我已经看到了很多关于可能的策略的答案,但是对于这个特定的用例,没有一个被认为是“最好的”或“标准”。我们正在使用C++11,因为它的价值。有些答案含糊地建议将字符串的内容复制到缓冲区中,并使用该缓冲区。但是怎么做呢?我希望在这次谈话中有更多的意见,这样我才能最终选择一个策略并坚持下去。
谢谢!
更新:下面是我使用的解决方案
我使用uint32_t来保持与其他API函数的一致性。bufferSize是一个引用,因为FORTRAN通过引用调用一切。
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参数,这样我就不必担心注释中提到的双重间接的一些问题。
发布于 2014-02-18 05:31:56
似乎getproperty API调用是有缺陷的。调用方无法说明value的长度。这意味着getproperty的实现不能安全地写入value,因为它不知道它有多长时间。getproperty方法需要更改为接受char** value或以value缓冲区的长度作为参数。让我们假设后者已经完成
void getproperty(const char* key, char* value, size_t valueLength);现在,为了复制从funcReturningString返回的值的内容,我们只需要使用strncpy
std::string stdString = funcReturningString();
strlcpy(value, stdString.c_str(), valueLength);注意,这仍然是有缺陷的。如果valueLength == 0或它小于字符串的长度,那么这是行不通的。最好将getproperty更改为还返回某种错误代码,这样就可以将这样的故障传递给调用方。
发布于 2014-02-18 05:36:49
一个简单的办法是:
strcpy(value, stdString.c_str());但是,您需要小心缓冲区溢出。理想情况下,此函数的调用方还应该提供它所提供的缓冲区的大小,以确保您不会写过它的末尾。这样做的一种方法是传递额外的参数buffer_size并使用
strncpy(value, stdString.c_str(), buffer_size);
if (buffer_size > 0) value[buffer_size-1] = 0;否则,在复制之前先缩短stdString。
发布于 2014-02-18 05:35:03
如果您需要得到可修改的值副本,您应该自己分配内存,value的类型也应该是指针到指针。
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上):
char* value = NULL;
getproperty("key", &value);
// use
...
// free it
free(value);https://stackoverflow.com/questions/21845034
复制相似问题