}
} // class VBByValStrMarshaler
-
-#if FEATURE_COMINTEROP
-
internal static class AnsiBSTRMarshaler
{
internal static unsafe IntPtr ConvertToNative(int flags, string strManaged)
}
} // class AnsiBSTRMarshaler
-#endif // FEATURE_COMINTEROP
-
-
internal static class WSTRBufferMarshaler
{
internal static IntPtr ConvertToNative(string strManaged)
EmitStoreManagedValue(pslILEmit);
}
-#ifdef FEATURE_COMINTEROP
LocalDesc ILAnsiBSTRMarshaler::GetNativeType()
{
LIMITED_METHOD_CONTRACT;
pslILEmit->EmitCALL(METHOD__ANSIBSTRMARSHALER__CLEAR_NATIVE, 1, 0);
}
+#ifdef FEATURE_COMINTEROP
+
LocalDesc ILHSTRINGMarshaler::GetNativeType()
{
LIMITED_METHOD_CONTRACT;
virtual void EmitConvertContentsNativeToCLR(ILCodeStream* pslILEmit);
};
-#ifdef FEATURE_COMINTEROP
class ILAnsiBSTRMarshaler : public ILMarshaler
{
public:
virtual bool NeedsClearNative();
virtual void EmitClearNative(ILCodeStream* pslILEmit);
};
-#endif // FEATURE_COMINTEROP
class ILLayoutClassPtrMarshalerBase : public ILMarshaler
{
}
m_type = MARSHAL_TYPE_BSTR;
break;
-#ifdef FEATURE_COMINTEROP
+
case NATIVE_TYPE_ANSIBSTR:
if (builder)
{
}
m_type = MARSHAL_TYPE_ANSIBSTR;
break;
-
+
case NATIVE_TYPE_TBSTR:
{
if (builder)
break;
}
+#ifdef FEATURE_COMINTEROP
case NATIVE_TYPE_BYVALSTR:
{
if (builder)
DEFINE_METHOD(BSTRMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_IntPtr_RetStr)
DEFINE_METHOD(BSTRMARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RetVoid)
-#ifdef FEATURE_COMINTEROP
DEFINE_CLASS(ANSIBSTRMARSHALER, StubHelpers, AnsiBSTRMarshaler)
DEFINE_METHOD(ANSIBSTRMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_Int_Str_RetIntPtr)
DEFINE_METHOD(ANSIBSTRMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_IntPtr_RetStr)
DEFINE_METHOD(ANSIBSTRMARSHALER, CLEAR_NATIVE, ClearNative, SM_IntPtr_RetVoid)
+#ifdef FEATURE_COMINTEROP
DEFINE_CLASS(OBJECTMARSHALER, StubHelpers, ObjectMarshaler)
DEFINE_METHOD(OBJECTMARSHALER, CONVERT_TO_NATIVE, ConvertToNative, SM_ObjIntPtr_RetVoid)
DEFINE_METHOD(OBJECTMARSHALER, CONVERT_TO_MANAGED, ConvertToManaged, SM_IntPtr_RetObj)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_LPSTR, CSTRMarshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_LPUTF8STR, CUTF8Marshaler, false)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_BSTR, BSTRMarshaler, false)
-#ifdef FEATURE_COMINTEROP
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_ANSIBSTR, AnsiBSTRMarshaler, false)
+#ifdef FEATURE_COMINTEROP
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_HSTRING, HSTRINGMarshaler, true)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_DATETIME, DateTimeMarshaler, true)
DEFINE_MARSHALER_TYPE(MARSHAL_TYPE_URI, UriMarshaler, true)
#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L)
#define UInt32x32To64(a, b) ((unsigned __int64)((ULONG)(a)) * (unsigned __int64)((ULONG)(b)))
+#define ARRAYSIZE(x) (sizeof(x)/sizeof(*x))
+
#ifndef TRUE
#define TRUE 1
#endif
DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer);
typedef WCHAR* BSTR;
-BSTR TP_SysAllocStringByteLen(LPSTR psz, size_t len);
+BSTR TP_SysAllocStringByteLen(LPCSTR psz, size_t len);
void TP_SysFreeString(BSTR bstr);
size_t TP_SysStringByteLen(BSTR bstr);
BSTR TP_SysAllocStringLen(LPWSTR psz, size_t len);
add_subdirectory(StringMarshalling/LPTSTR)
add_subdirectory(StringMarshalling/UTF8)
add_subdirectory(StringMarshalling/BSTR)
+add_subdirectory(StringMarshalling/AnsiBSTR)
add_subdirectory(MarshalAPI/FunctionPointer)
add_subdirectory(MarshalAPI/IUnknown)
add_subdirectory(SizeConst)
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+using NativeDefs;
+using System.Diagnostics;
+
+class Test
+{
+
+ #region "Report Failure"
+ static int fails = 0; //record the fail numbers
+ // Overload methods for reportfailure
+ static int ReportFailure(string s)
+ {
+ Console.WriteLine(" === Fail:" + s);
+ return (++fails);
+ }
+ static int ReportFailure(string expect, string actual)
+ {
+ Console.WriteLine(" === Fail: Expected:" + expect + "\n Actual:" + actual);
+ return (++fails);
+ }
+ static int ReportFailure(string describe, string expect, string actual)
+ {
+ Console.WriteLine(" === Fail: " + describe + "\n\tExpected:" + expect + "\n\tActual:" + actual);
+ return (++fails);
+ }
+ #endregion
+
+ #region "Helper"
+ // ************************************************************
+ // Returns the appropriate exit code
+ // *************************************************************
+ static int ExitTest()
+ {
+ if (fails == 0)
+ {
+ Console.WriteLine("PASS");
+ return 100;
+ }
+ else
+ {
+ Console.WriteLine("FAIL - " + fails + " failure(s) occurred");
+ return 101;
+ }
+ }
+ #endregion
+
+ public static int Main(string[] args)
+ {
+ string strManaged = " \0Managed\0String\0 ";
+ string strRet = "a";
+ string strNative = "Native String";
+
+ //since the out attributes doesnt work for string, so i dont check the out value.
+ string strPara2 = strManaged;
+ string strRet2 = AnsiBStrTestNative.Marshal_InOut(strPara2);
+ if (!strRet2.Equals(strRet))
+ {
+ ReportFailure("Method AnsiBStrTestNative.Marshal_InOut[Managed Side],The Return string is wrong", strRet, strRet2);
+ }
+ if (!strPara2.Equals(strManaged))
+ {
+ ReportFailure("Method AnsiBStrTestNative.Marshal_InOut[Managed Side],The Parameter string is Changed", strManaged, strPara2);
+ }
+
+ //TestMethod3
+ string strPara3 = strManaged;
+ string strRet3 = AnsiBStrTestNative.Marshal_Out(strPara3);
+ if (!strRet.Equals(strRet3))
+ {
+ ReportFailure("Method AnsiBStrTestNative.Marshal_Out[Managed Side],The Return string is wrong", strRet, strRet3);
+ }
+ if (!strPara3.Equals(strManaged))
+ {
+ ReportFailure("Method AnsiBStrTestNative.Marshal_Out[Managed Side],The Parameter string is not Changed", strManaged, strPara3);
+ }
+
+ //TestMethod5
+ string strPara5 = strManaged;
+ string strRet5 = AnsiBStrTestNative.MarshalPointer_InOut(ref strPara5);
+
+ if (!strRet5.Equals(strRet))
+ {
+ ReportFailure("Method AnsiBStrTestNative.MarshalPointer_InOut[Managed Side],The Return string is wrong", strRet, strRet5);
+ }
+ if (!strPara5.Equals(strNative))
+ {
+ ReportFailure("Method AnsiBStrTestNative.MarshalPointer_InOut[Managed Side],The Passed string is wrong", strNative, strPara5);
+ }
+
+ //TestMethod6
+ string strPara6 = strManaged;
+ string strRet6 = AnsiBStrTestNative.MarshalPointer_Out(out strPara6);
+ if (!strRet6.Equals(strRet))
+ {
+ ReportFailure("Method AnsiBStrTestNative.MarshalPointer_Out[Managed Side],The Return string is wrong", strRet, strRet6);
+ }
+ if (!strPara6.Equals(strNative))
+ {
+ ReportFailure("Method AnsiBStrTestNative.MarshalPointer_Out[Managed Side],The Passed string is wrong", strNative, strPara6);
+ }
+
+ return ExitTest();
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <AssemblyName>AnsiBStrTest</AssemblyName>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{176EC495-7AE9-42CF-A591-06A382DB4048}</ProjectGuid>
+ <OutputType>exe</OutputType>
+ <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+ <DefineConstants>$(DefineConstants);STATIC</DefineConstants>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="*.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Common\CoreCLRTestLibrary\CoreCLRTestLibrary.csproj">
+ <Project>{c8c0dc74-fac4-45b1-81fe-70c4808366e0}</Project>
+ <Name>CoreCLRTestLibrary</Name>
+ </ProjectReference>
+ <ProjectReference Include="CMakeLists.txt">
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+#include <xplatform.h>
+#include "platformdefines.h"
+
+const char strManaged[] = " \0Managed\0String\0 ";
+size_t lenstrManaged = ARRAYSIZE(strManaged) - 1; // the length of strManaged
+
+const char strReturn[] = "a";
+size_t lenstrReturn = ARRAYSIZE(strReturn) - 1; //the length of strReturn
+
+const char strNative[] = "Native String";
+size_t lenstrNative = ARRAYSIZE(strNative) - 1; //the len of strNative
+
+//Test Method1
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_In(/*[in]*/ BSTR s)
+{
+ //Check the input
+ size_t len = TP_SysStringByteLen(s);
+ if ((len != lenstrManaged) || (memcmp(s, strManaged, len) != 0))
+ {
+ printf("Error in Function Marshal_In(Native Client)\n");
+
+ //Expected
+ printf("Expected:");
+ for (size_t i = 0; i < lenstrManaged; ++i)
+ putchar(*(((char *)strManaged) + i));
+ printf("\tThe length of Expected:%zd\n", lenstrManaged);
+
+ //Actual
+ printf("Actual:");
+ for (size_t j = 0; j < len; ++j)
+ putchar(*(((char *)s) + j));
+ printf("\tThe length of Actual:%zd\n", len);
+ }
+
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
+
+//Test Method2
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_InOut(/*[In,Out]*/ BSTR s)
+{
+
+ //Check the Input
+ size_t len = TP_SysStringByteLen(s);
+ if ((len != lenstrManaged) || (memcmp(s, strManaged, len) != 0))
+ {
+ printf("Error in Function Marshal_InOut(Native Client)\n");
+
+ //Expected
+ printf("Expected:");
+ for (size_t i = 0; i < lenstrManaged; ++i)
+ putchar(*(((char *)strManaged) + i));
+ printf("\tThe length of Expected:%zd\n", lenstrManaged);
+
+ //Actual
+ printf("Actual:");
+ for (size_t j = 0; j < len; ++j)
+ putchar(*(((char *)s) + j));
+ printf("\tThe length of Actual:%zd\n", len);
+ }
+
+ //In-Place Change
+ memcpy((char *)s, strNative, lenstrNative);
+ *((UINT *)s - 1) = (UINT) TP_SysStringByteLen(s);
+
+ //Return
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE Marshal_Out(/*[Out]*/ BSTR s)
+{
+ s = TP_SysAllocStringByteLen(strNative, lenstrNative);
+
+ //In-Place Change
+ memcpy((char *)s, strNative, lenstrNative);
+ *((UINT *)s - 1) = (UINT) TP_SysStringByteLen(s);
+
+ //Return
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
+
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_In(/*[in]*/ BSTR *s)
+{
+ //CheckInput
+ size_t len = TP_SysStringByteLen(*s);
+ if ((len != lenstrManaged) || (memcmp(*s, strManaged, len) != 0))
+ {
+ printf("Error in Function MarshalPointer_In\n");
+
+ //Expected
+ printf("Expected:");
+ for (size_t i = 0; i < lenstrManaged; ++i)
+ putchar(*(((char *)strManaged) + i));
+ printf("\tThe length of Expected:%zd\n", lenstrManaged);
+
+ //Actual
+ printf("Actual:");
+ for (size_t j = 0; j < len; ++j)
+ putchar(*(((char *)*s) + j));
+ printf("\tThe length of Actual:%zd\n", len);
+ }
+
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
+
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_InOut(/*[in,out]*/ BSTR *s)
+{
+ //Check the Input
+ size_t len = TP_SysStringByteLen(*s);
+ if ((len != lenstrManaged) || (memcmp(*s, strManaged, len) != 0))
+ {
+ printf("Error in Function MarshalPointer_InOut\n");
+
+ //Expected
+ printf("Expected:");
+ for (size_t i = 0; i < lenstrManaged; ++i)
+ putchar(*(((char *)strManaged) + i));
+
+ printf("\tThe length of Expected:%zd\n", lenstrManaged);
+
+ //Actual
+ printf("Actual:");
+ for (size_t j = 0; j < len; ++j)
+ putchar(*(((char *)*s) + j));
+
+ printf("\tThe length of Actual:%zd\n", len);
+ }
+
+ //Allocate New
+ TP_SysFreeString(*s);
+ *s = TP_SysAllocStringByteLen(strNative, lenstrNative);
+
+ //Return
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
+
+extern "C" DLL_EXPORT BSTR STDMETHODCALLTYPE MarshalPointer_Out(/*[out]*/ BSTR *s)
+{
+ *s = TP_SysAllocStringByteLen(strNative, lenstrNative);
+ return TP_SysAllocStringByteLen(strReturn, lenstrReturn);
+}
--- /dev/null
+cmake_minimum_required (VERSION 2.6)
+project (AnsiBStrTestNative)
+include_directories(${INC_PLATFORM_DIR})
+set(SOURCES AnsiBStrTestNative.cpp)
+
+# add the executable
+add_library (AnsiBStrTestNative SHARED ${SOURCES})
+
+if(WIN32)
+ list(APPEND LINK_LIBRARIES_ADDITIONAL
+ OleAut32.lib
+ )
+endif(WIN32)
+
+target_link_libraries(AnsiBStrTestNative ${LINK_LIBRARIES_ADDITIONAL})
+
+# add the install targets
+install (TARGETS AnsiBStrTestNative DESTINATION bin)
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+using System;
+using System.Reflection;
+using System.Text;
+
+#pragma warning disable CS0618
+
+namespace NativeDefs
+{
+ public static class AnsiBStrTestNative
+ {
+ public const string NativeBinaryName = nameof(AnsiBStrTestNative);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.AnsiBStr)]
+ public static extern string Marshal_InOut([In, Out][MarshalAs(UnmanagedType.AnsiBStr)]string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.AnsiBStr)]
+ public static extern string Marshal_Out([Out][MarshalAs(UnmanagedType.AnsiBStr)]string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.AnsiBStr)]
+ public static extern string MarshalPointer_InOut([MarshalAs(UnmanagedType.AnsiBStr)]ref string s);
+
+ [DllImport(NativeBinaryName)]
+ [return: MarshalAs(UnmanagedType.AnsiBStr)]
+ public static extern string MarshalPointer_Out([MarshalAs(UnmanagedType.AnsiBStr)]out string s);
+ }
+}
#else
#include "types.h"
-
#endif
#include <wchar.h>