你能把LPTSTR投射到BSTR吗?

将LPTSTR直接转换为BSTR是合法的吗? 根据我对BSTR的理解,直接将一个LPTSTR转换为BSTR会给你留下一个损坏的长度前缀。示例代码明确指出字符串文字不能存储到BSTR。任何人都可以向我确认LPTSTR / LPCTSTR不能在不破坏长度前缀的情况下直接转换为BSTR吗? 编辑: 我的困惑是看到在调用COM对象时使用它。事实证明,在编译COM dll时,会生成一个.tli文件,用于创建中间方法。此方法采用类型
_bstr_t
_bstr_t
可以在其构造函数中使用
LPTSTR
,因此一切运行顺利。     
已邀请:
如果你的程序是unicode而你的
LPTSTR
LPWSTR
,你可以使用SysAllocString将指针转换为宽字符串到
BSTR
。 直接强制转换是不可能的,因为两者具有不同的内存表示。 如果使用C ++,则可以使用_bstr_t类来简化
BSTR
字符串的使用。     
如果你试图将
LPCTSTR
s作为
BSTR
s传递,你会发现你会随机炸掉你附近的任何互操作编组码。编组将拉出4字节前缀(这是随机数据)为
LPCTSTR
并尝试和Marshall字符串。 您会发现4字节前缀原来是缓冲区之前的堆栈内容,甚至是前面字符串中更好的字符数据。然后你会尝试编组兆字节的数据... :-) 如果需要保留
BSTR
指针,请使用
CComBSTR
包装并使用
.Detach()
。 如果编译器在这个问题上发出警告,那就太好了。     
LPTSTR是一个指向char数组的指针(或者确切地说是TCHAR) BSTR是由结构(或复合数据)组成的 *长度前缀 *数据字符串 *终结者 所以铸造不起作用     
它不可能,因为那么在
LPTSTR
之前的内存中的四个字节将被视为结果的长度
BSTR
。这可能会导致现场出现内存保护错误(不太可能),但肯定会导致
BSTR
的长度可能大于原始长度
LPTSTR
。因此,当有人试图从中读取或写入时,他们可能会访问无效的内存。     
不,您不能 - 如果认为它是BSTR的代码调用SysStringLen(),它将遇到未定义的行为,因为该函数依赖于某些特定于实现的服务数据。     
你不能施放,你必须转换。您可以使用内置编译器内部
_bstr_t
(来自
comutil.h
)来帮助您轻松完成此操作。样品:
#include <Windows.h>
#include <comutil.h>

#pragma comment( lib, "comsuppwd.lib")

int main()
{
    LPTSTR p = "Hello, String";
    _bstr_t bt = p;
    BSTR bstr = bt;
    bstr;
}
    
不,你不能直接施放它们。但是,您可以创建一个同时执行这两者的字符串。 C-String没有4字节的头。但是,中间的位是相同的,所以如果你发现自己需要两个表示,那么创建一个包装类,用于构造一个带有4byte头和一个空终止符的字符串,但是可以返回BSTR部分和C-String的访问器。 这段代码是一个不完整的例子,我没有编译过这个!
class YetAnotherStringType //just what the world needs
{
  public:
  YetAnotherStringType(const char *str)
  { 
     size_t slen = strlen(str);
     allocate(slen);
     set_size_dword(slen);  
     copy_cstr(str, slen);     
  }

  const char *get_cstr() const
  {
     return &m_data[4];
  }

  const BSTR get_bstr() const
  {
     return (BSTR*)m_data;
  }

  void copy_cstr(const char *cstr, int size = -1)
  {
      if (size == -1)
         size = strlen(cstr);
      memcpy(&m_data[4], cstr, size + 1); //also copies first null terminator
      m_data[5 + size] = 0; //add the second null terminator
  }

  void set_size_dword(size_t size)
  {
     *((unsigned int*)m_data) = size;
  }

  void allocate(size_t size)
  {
     m_data = new char[size + 6]; //enough for double terminator
  }

  char *m_data;
};
    
一般来说没有,但有一些方法可以通过辅助类和宏在某种程度上使它们兼容(见下文)。 1:1映射永远不可能的主要原因是
BSTR
(因此
CComBSTR
在字符串中可以包含
''
,因为它最终是一个计数的字符串类型。 使用C ++时最好的选择是使用ATL类
CComBSTR
代替
BSTR
。在任何一种情况下,您都可以使用ATL / MFC转换宏
CW2A
和朋友。 另请注意,文档(MSDN)说:   推荐的转换方式   从
BSTR
字符串是使用   
CComBSTR
上课。要转换成
BSTR
,   将现有字符串传递给   
CComBSTR
的构造函数。转换   来自BSTR,使用   
COLE2
[
C
] DestinationType [
EX
],例如   
COLE2T
。 ...适用于您的用例。 请参阅John Dibling的答案(
_bstr_t
)。     

要回复问题请先登录注册