(EDIT:MFC)CString类的对象的内部结构是什么
What is the internal structure of an object of the (EDIT: MFC) CString class?
我需要(有效地)从(Edit:MFC)CString对象strncpy()
到C字符串变量。众所周知,strncpy()
有时无法正确终止dest C字符串(具体取决于源长度**EDIT和调用中指定的长度)。为了避免这种邪恶,我想在CString源对象中存储一个NUL字符,然后将其存储到strcpy()
或memmove()
中。
这样做合理吗?如果是,我必须在CString对象内部操作什么?如果没有,那么有什么替代方案可以保证正确终止的目的地C字符串?
strncpy()
仅在源字符串超过指定的长度限制时"失败"为null终止目标字符串。您可以通过自己将目的地的最后一个字符设置为null来确保目的地是null终止的。例如:
#define DEST_STR_LEN 10
char dest_str[DEST_STR_LEN + 1]; // +1 for the null
strncpy(dest_str, src_str, DEST_STR_LEN);
dest_str[DEST_STR_LEN] = ' ';
如果src_str
的长度超过DEST_STR_LEN
个字符,则dest_str
将是一个正确终止的DEST_STR_LEN
字符字符串。如果src_str
比它短,strncpy()
将在dest_str
内的某个位置放置一个null终止符,因此最末端的null是不相关且无害的。
CSimpleStringT::GetString提供一个指向以null结尾的字符串的指针。以此作为strncpy
的来源。由于这是C++,所以在与遗留API接口时应该只使用C样式字符串。请改用std::string
。
替代方法之一是先将字符串归零,然后从CString强制转换或memcpy。
我希望它们与我使用它们时没有改变:那是多年前的事了:)
他们使用了一个有趣的"技巧"来处理refcount和非常快速高效的自动转换为char*:即指针指向LPCSTR,但保留了一些后字节以保持实现状态。
因此,结构可以与旧的windows API(LPCSTR,无开销)一起使用。我当时觉得这个主意很有趣!
当然,关键是分配器的可用性:它们只是在mallocating/free时偏移指针。
我记得有一个缓冲区请求(例如)修改可用数据:GetBuffer(0),然后是ReleaseBuffer()。
HTH
如果您没有在启用_UNICODE
的情况下进行编译,那么您可以很容易地从CString
获得const char *
。只需将其投射到LPCTSTR
:
CString myString("stuff");
const char *byteString = (LPCTSTR)myString;
这保证是以NULL终止的。
如果使用_UNICODE
构建,则CString
是UTF-16编码的字符串。你真的不能直接用它做任何事情。
如果您确实需要从CString
复制数据,这非常容易,即使使用C样式代码也是如此。只需确保您分配了足够的内存并复制了正确的长度:
CString myString("stuff");
char *outString = (char*)malloc(myString.Length() + 1);
strncpy(outString, (LPCTSTR)myString, myString.Length());
CString以NULL结尾,因此只要文本正确(内部没有NULL字符),复制就应该是安全的。你可以写:
char szStr[256];
strncpy(szStr, (LPCSTR) String, 3);
szStr[3]=' '; /// b-cos no null-character is implicitly appended to the end of destination
如果在CString对象中存储null somehere,可能会给自己带来更多问题,CString会在内部存储其长度。
另一种替代解决方案更倾向于CPU或编译器的支持,因为这是一种更好的方法-只需确保在"安全"模式下复制内存时,在每次原子操作后的任何时候,末尾都会添加零,因此当整个循环失败时,目标字符串仍将终止,而无需在复制前将其完全清零。也可以支持快速清零——只需标记清零区域的开始和停止,它就会立即在RAM中清除,这会让事情变得容易得多。
- 如何从传递到对象的对象内部访问对象的类属性?
- 对象内部对象的重载功能
- 为什么我不能更改实例化对象内部的向量?
- 对象内部有大量数据容器,实现更高效的对象交换
- 微机器人 - 检查点是否在对象内部
- C++:访问对象内部子对象的方法
- 如果访问对象,则指向的对象内部的指针会更改内存位置
- shared_ptr - 从包含的对象内部访问
- 如何创建功能以用受保护或私人侵犯的对象在对象内部操纵对象
- 如何从对象内部的 typedef 获取模板参数类型
- DirectX 11渲染对象内部
- 引用对象内部的指针
- 访问对象内部的指针
- 访问检测到的对象/c++内部的像素值
- 如何在linux x64上创建共享库对象,该对象内部使用C++异常,并且可以在旧平台上运行
- OpenGL检测单击另一个对象内部的对象
- 如何在类对象内部分配数组
- 在基类对象内部创建派生类对象
- 多态对象内部的C++引用
- 在C++中,如何在没有动态分配(即NEW)的情况下将对象初始化为对象内部的指针