1 /***
2 *marshal_atl.h
3 *
4 *           Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:     Marshalling classes
7 *
8 *           [Public]
9 *
10 ****/
11
12 #pragma once
13
14 #ifndef _INC_MSCLR_MARSHAL_ATL
15 #define _INC_MSCLR_MARSHAL_ATL
16
17 #include <atlsafe.h>
18 #include <atlbase.h>
19 #include <atlstr.h>
20 #include <vcclr.h>
21 #include <atlcomcli.h> 
22
23 #include <msclr\marshal.h>
24
25 #using <mscorlib.dll>
26
27 namespace msclr{
28     namespace interop{
29
30 template <>
31 inline System::String^ marshal_as(const CComBSTR& _from_object)
32 {
33     if (_from_object.m_str == NULL)
34     {
35         return nullptr;
36     }
37     // Using PtrToStringBSTR here instead of marshal_as<String^, BSTR>() because we want to perserve the embedded NULLs
38     return System::Runtime::InteropServices::Marshal::PtrToStringBSTR(System::IntPtr(_from_object.m_str));
39 }
40
41 template <>
42 inline CComBSTR marshal_as(System::String^ const& _from_object)
43 {
44     if (_from_object == nullptr)
45     {
46         return CComBSTR(static_cast<const wchar_t*>(NULL));
47     }
48     if(_from_object->Length == 0)
49     {
50         return CComBSTR(static_cast<const wchar_t*>(L""));
51     }
52
53     cli::pin_ptr<const wchar_t> _pinned_ptr = PtrToStringChars(_from_object);
54     return  CComBSTR( _from_object->Length, static_cast<const wchar_t *>(_pinned_ptr));
55 }
56
57 template <>
58 inline System::String^ marshal_as(const CStringA& _from_obj)
Lines 59 ... 68 are skipped.
69
70 template <>
71 inline CStringA marshal_as(System::String^ const & _from_obj)
72 {
73     if (_from_obj == nullptr)
74     {
75         throw gcnew System::ArgumentNullException(_EXCEPTION_NULLPTR);
76     }
77     CStringA _to_obj;
78     size_t _size = details::GetAnsiStringSize(_from_obj);
79     
80     //checking for overflow
81     if (_size > INT_MAX)
82     {
83         throw gcnew System::ArgumentOutOfRangeException(_EXCEPTION_NULLPTR);
84     }
85
86     int _length = static_cast<int>(_size)-1;
87     
88     //GetBuffer() throws, so we don't need to check for NULL
89     char* _dest_buf = _to_obj.GetBuffer(_length); 
90
91     details::WriteAnsiString(_dest_buf, _size, _from_obj);
92     _to_obj.ReleaseBuffer(_length); // We don't want to include the NULL.  This call will set the length to _length
93
94     return _to_obj;
95 }
96
97 template <>
98 inline CStringW marshal_as(System::String^ const & _from_obj)
99 {
100     if (_from_obj == nullptr)
101     {
102         throw gcnew System::ArgumentNullException(_EXCEPTION_NULLPTR);
103     }
104     cli::pin_ptr<const wchar_t> _pinned_ptr = PtrToStringChars(_from_obj);
105     return CStringW(static_cast<const wchar_t *>(_pinned_ptr), _from_obj->Length);
106 }
107
108     } //namespace interop
109 } //namespace msclr
110
111 #endif // _INC_MSCLR_MARSHAL_ATL
112