fork download
  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4.  
  5. using OLECHAR = wchar_t;
  6. using BSTR = OLECHAR*;
  7. using UINT = unsigned int;
  8.  
  9. UINT SysStringLen(BSTR str)
  10. {
  11. return (str) ? *(reinterpret_cast<UINT*>(str) - 1) : 0;
  12. }
  13.  
  14. BSTR SysAllocStringLen(const OLECHAR *strIn, UINT ui)
  15. {
  16. char *res = new char[sizeof(UINT) + ((ui + 1) * sizeof(OLECHAR))];
  17. *(reinterpret_cast<UINT*>(res)) = ui;
  18. BSTR ptr = reinterpret_cast<BSTR>(res + sizeof(UINT));
  19. if (strIn) memcpy(ptr, strIn, sizeof(OLECHAR) * ui);
  20. ptr[ui] = L'\0';
  21. return ptr;
  22. }
  23.  
  24. BSTR SysAllocString(const OLECHAR *psz)
  25. {
  26. if (!psz) return nullptr;
  27. const OLECHAR *ptr = psz;
  28. UINT len = 0;
  29. while (*ptr++ != L'\0') ++len;
  30. return SysAllocStringLen(psz, len);
  31. }
  32.  
  33. void SysFreeString(BSTR str)
  34. {
  35. if (str)
  36. delete[] reinterpret_cast<char*>((reinterpret_cast<UINT*>(str)-1));
  37. }
  38.  
  39. static BSTR Concatenate2BSTRs(BSTR a, BSTR b)
  40. {
  41. auto lengthA = SysStringLen(a);
  42. auto lengthB = SysStringLen(b);
  43.  
  44. auto result = SysAllocStringLen(NULL, lengthA + 1 + lengthB);
  45. if (result) {
  46. memcpy(result, a, lengthA * sizeof(OLECHAR));
  47. result[lengthA] = L' ';
  48. memcpy(result + lengthA + 1, b, lengthB * sizeof(OLECHAR));
  49. // no need to null-terminate manually, SysAllocStringLen() already did it...
  50. //result[lengthA + 1 + lengthB] = L'\0';
  51. }
  52.  
  53. return result;
  54. }
  55.  
  56. int main()
  57. {
  58. BSTR a = SysAllocString(L"hello");
  59. BSTR b = SysAllocString(L"world");
  60. BSTR c = Concatenate2BSTRs(a, b);
  61.  
  62. wcout << SysStringLen(a) << L' ' << a << endl;
  63. wcout << SysStringLen(b) << L' ' << b << endl;
  64. wcout << SysStringLen(c) << L' ' << c << endl;
  65.  
  66. SysFreeString(a);
  67. SysFreeString(b);
  68. SysFreeString(c);
  69.  
  70. return 0;
  71. }
Success #stdin #stdout 0.01s 5516KB
stdin
Standard input is empty
stdout
5 hello
5 world
11 hello world