小弟初学COM,碰到以下问题
函数在IDL里声明
[
object,
uuid(25ABD15A-3B45-4E53-8CFB-70B0C5D6F0F0),
helpstring("IXEngine Interface"),
pointer_default(unique)
]
interface IX : IUnknown
{
[helpstring("Method CreateSession")]
HRESULT CreateSession([in] GUID cookie, [in, string] BSTR alias, [out] IXSession **ppISession);在客户机端,我调用这个进程外COM,然后跟踪到CreateSession中,发现
hr = p->CreateSession(cookie, L"abcd", &ps);cookie能正确的被客户端传送到服务器,但是传入的字符串abcd,到了服务器那就变成了空如果换成这样调用
wchar_t *str = new wchar_t(5);
wcscpy(str, L"abcd");
hr = p->CreateSession(cookie, L"abcd", &ps);
CreateSession直接返回E_OUTOFMEMORY,连在服务器里设的断点都跑不到,我的理解就是在代理存根那的调用就失败返回了。但是不知道什么原因

解决方案 »

  1.   

    产生BSTR可以使用SysAllocString,释放BSTR可能过SysFreeString。
    或者直接使用ATL中的CComBSTR也可以。
      

  2.   

    不是这个原因, BSTR 就是 WCHAR *
      

  3.   

    “BSTR就是WCHAR *”,那只是从表面类型来看是这样。实际上。COM中的BSTR要求在字符缓冲区的前面,附上四个字节的长度信息,而一般的WCHAR字符串当然没这种要求。
    而使用SysAllocString创建出来的BSTR,天生就满足COM的要求,因为它不仅仅是创建一个WCHAR*缓冲区。
      

  4.   

    正解
    这也是com的优势
    bstr很强大
      

  5.   

    确实这样!不过楼主hr = p->CreateSession(cookie, L"abcd", &ps); 传过去以后也应该看到L"cd"也两个字符,而不是空串。我觉得原因可能还是因为楼主创建的"进程外COM",而第二参数是本地内存指针,传过去以后server端内存指针不同。导致这种情况应该是代理存根的问题.
      

  6.   

    最好使用_bstr_t类。它封装的比较好,能在各种字符串类型间互相转换。
      

  7.   

    怎么会是“cd”,长度信息应该在a的位置之前,而不是把ab的位置当做长度信息。
      

  8.   

    我是说楼主那种调用方式直接传L"abcd",不是正好把L"ab"这4个字节当成长度信息了么
      

  9.   

    不会的。
    BSTR从类型上看就是WCHAR*,但指针指向的位置不是整个BSTR数据的开头,而是从实际的字符开始,也就是说,BSTR是指在整个BSTR加4个字节的地方。COM在使用时把些地址减去4,并从哪里取得字符串的长度信息。
    如果直接传递L"abcd",结果就是在内存里,把字符'a'之前的4个字节给当成了长度,而那个位置上本来应该是什么信息,不得而知,结果当然也就乱了。