// public static void SetDelegate(IntPtr ,IntPtr ) // ( ReturnValue==null) public static bool CallAsFunc(int Target, IntPtr Ptr, IntPtr ReturnValue, IntPtr , int ) // 1 public static int GetNParams(int Target, IntPtr Ptr) // public static bool SetPropVal(int Target, IntPtr Ptr, IntPtr pvarPropVal) public static bool GetPropVal(int Target, IntPtr Ptr, IntPtr varPropVal) // public static void DeleteObject(int Target)
typedef bool(STDMETHODCALLTYPE *ManagedCallAsFunc)(const __int32, const wchar_t*, tVariant* pvarRetValue, tVariant* paParams, const __int32 lSizeArray); typedef int(STDMETHODCALLTYPE *ManagedGetNParams)(const __int32, const wchar_t*); typedef bool(STDMETHODCALLTYPE *ManagedGetPropVal)(const __int32, const wchar_t*, tVariant*); typedef bool(STDMETHODCALLTYPE *ManagedSetPropVal)(const __int32, const wchar_t*, tVariant*); typedef void(STDMETHODCALLTYPE *ManagedSetDelegate)(void*(*) (long), void(*) (const wchar_t*)); typedef void(STDMETHODCALLTYPE *ManagedDeleteObject)(const __int32);
bool ManagedDomainLoader::CreateDelegate(DWORD appDomainID, wstring MethodName, INT_PTR * fnPtr) { HRESULT hr = ClrLoader::pClrLoader->pCLRRuntimeHost->CreateDelegate( appDomainID, L"NetObjectToNative", // L"NetObjectToNative.AutoWrap", // MethodName.c_str(), // (INT_PTR*)fnPtr); // if (FAILED(hr)) { wprintf_s(L"Failed to create a delegate to the managed entry point: %s\n", MethodName.c_str()); printf_s("Failed to create a delegate to the managed entry point: (%d).\n", hr); ClrLoader::pClrLoader->pCLRRuntimeHost->UnloadAppDomain(appDomainID, true); return false; } return true; }
if (!CreateDelegate(domainId,L"CallAsFunc", (INT_PTR*)&pCallAsFunc)) return false; if (!CreateDelegate(domainId, L"GetNParams", (INT_PTR*)&pGetNParams)) return false; if (!CreateDelegate(domainId, L"GetPropVal", (INT_PTR*)&pGetPropVal)) return false; if (!CreateDelegate(domainId, L"SetPropVal", (INT_PTR*)&pSetPropVal)) return false; if (!CreateDelegate(domainId, L"DeleteObject", (INT_PTR*)&pDeleteObject)) return false; if (!CreateDelegate(domainId, L"SetDelegate", (INT_PTR*)&pSetDelegate)) return false; // pSetDelegate(ManagedDomainLoader::GetMem, ManagedDomainLoader::AddError);
public struct { internal AutoWrap ; internal int Next; internal (AutoWrap ) { this. = ; Next = -1; } internal (AutoWrap , int next) { this. = ; Next = next; } } internal class { List<> = new List<>(); int FirstDeleted = -1; public int Add(AutoWrap ) { var = new (); // , if (FirstDeleted == -1) { .Add(); return .Count-1; } else { // // int newPos = FirstDeleted; FirstDeleted = [newPos].Next; [newPos] = ; return newPos; } } public void RemoveKey(int Pos) { if (Pos > 0 && Pos < .Count && [Pos]. != null) { var = new (null, FirstDeleted); [Pos] =; FirstDeleted = Pos; } } public AutoWrap GetValue(int Pos) { if (!(Pos > -1 && Pos < .Count && [Pos]. != null)) return null; return [Pos].; } }
public class AutoWrap { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate IntPtr Delegate(int ); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void Delegate(IntPtr ); // internal static ; // 1, . Byte[] // internal static string = "<>№_%)?&";//new Guid().GetHashCode(); // protected internal object O = null; // . protected internal Type T = null; protected internal int ; // internal bool ; // Enum.Parse(T, name); internal bool IsEnum; // ExpandoObject . // DynamicObject DynamicMetaObject internal bool ExpandoObject; // COM internal static bool = false; internal static bool = true; internal static Exception = null; // internal static Delegate ; // internal static Delegate ; // . public static void SetDelegate(IntPtr ,IntPtr ) { = Marshal.GetDelegateForFunctionPointer<Delegate>(); = Marshal.GetDelegateForFunctionPointer<Delegate>(); } static AutoWrap() { // // , // 0 = new (); var = new AutoWrap(typeof(NetObjectToNative)); } public AutoWrap(object obj) { = .Add(this); O = obj; if (O is Type) { T = O as Type; = true; } else { T = O.GetType(); = false; ExpandoObject = O is System.Dynamic.ExpandoObject; IsEnum = T.GetTypeInfo().IsEnum; } } // public AutoWrap(object obj, Type type) { = .Add(this); O = obj; T = type; = false; // ExpandoObject = O is System.Dynamic.ExpandoObject; }
// struct _tVariant // { // _ANONYMOUS_UNION union // { // int8_t i8Val; // int16_t shortVal; // int32_t lVal; // int intVal; // unsigned int uintVal; // int64_t llVal; // uint8_t ui8Val; // uint16_t ushortVal; // uint32_t ulVal; // uint64_t ullVal; // int32_t errCode; // long hRes; // float fltVal; // double dblVal; // bool bVal; // char chVal; // wchar_t wchVal; // DATE date; // IID IDVal; // struct _tVariant *pvarVal; // struct tm tmVal; // _ANONYMOUS_STRUCT struct // { // void* pInterfaceVal; // IID InterfaceID; // } // __VARIANT_NAME_2/*iface*/; // _ANONYMOUS_STRUCT struct // { // char* pstrVal; // uint32_t strLen; //count of bytes //} //__VARIANT_NAME_3/*str*/; // _ANONYMOUS_STRUCT struct // { // WCHAR_T* pwstrVal; //uint32_t wstrLen; //count of symbol // } __VARIANT_NAME_4/*wstr*/; // } __VARIANT_NAME_1; // uint32_t cbElements; //Dimension for an one-dimensional array in pvarVal //TYPEVAR vt; //}; public enum EnumVar { VTYPE_EMPTY = 0, VTYPE_NULL, VTYPE_I2, //int16_t VTYPE_I4, //int32_t VTYPE_R4, //float VTYPE_R8, //double VTYPE_DATE, //DATE (double) VTYPE_TM, //struct tm VTYPE_PSTR, //struct str string VTYPE_INTERFACE, //struct iface VTYPE_ERROR, //int32_t errCode VTYPE_BOOL, //bool VTYPE_VARIANT, //struct _tVariant * VTYPE_I1, //int8_t VTYPE_UI1, //uint8_t VTYPE_UI2, //uint16_t VTYPE_UI4, //uint32_t VTYPE_I8, //int64_t VTYPE_UI8, //uint64_t VTYPE_INT, //int Depends on architecture VTYPE_UINT, //unsigned int Depends on architecture VTYPE_HRESULT, //long hRes VTYPE_PWSTR, //struct wstr VTYPE_BLOB, //means in struct str binary data contain VTYPE_CLSID, //UUID VTYPE_STR_BLOB = 0xfff, VTYPE_VECTOR = 0x1000, VTYPE_ARRAY = 0x2000, VTYPE_BYREF = 0x4000, //Only with struct _tVariant * VTYPE_RESERVED = 0x8000, VTYPE_ILLEGAL = 0xffff, VTYPE_ILLEGALMASKED = 0xfff, VTYPE_TYPEMASK = 0xfff, VTYPE_AutoWrap = 0xff // // 1 }; public class { internal static Dictionary<Type, EnumVar> ; static () { = new Dictionary<Type, EnumVar>() { { typeof(Int16),EnumVar.VTYPE_I2 }, {typeof(Int32),EnumVar.VTYPE_I4 }, {typeof(float),EnumVar.VTYPE_R4 }, {typeof(double),EnumVar.VTYPE_R8 }, {typeof(bool),EnumVar.VTYPE_BOOL }, {typeof(sbyte),EnumVar.VTYPE_I1 }, {typeof(byte),EnumVar.VTYPE_UI1 }, {typeof(UInt16),EnumVar.VTYPE_UI2}, {typeof(UInt32),EnumVar.VTYPE_UI4}, {typeof(Int64),EnumVar.VTYPE_I8}, {typeof(UInt64),EnumVar.VTYPE_UI8}, {typeof(string),EnumVar.VTYPE_PWSTR}, {typeof(byte[]),EnumVar.VTYPE_BLOB}, {typeof(DateTime),EnumVar.VTYPE_DATE}, {typeof(AutoWrap),EnumVar.VTYPE_AutoWrap}, }; } public static DateTime ConvertTmToDateTime(IntPtr ) { tm val = Marshal.PtrToStructure<tm>(); return val.ToDateTime(); } public static object IntPtr(IntPtr ) { IntPtr = + 44; int IntPtr = Marshal.SizeOf<IntPtr>(); EnumVar =(EnumVar) Marshal.ReadInt16(); switch () { case EnumVar.VTYPE_EMPTY: case EnumVar.VTYPE_NULL: return null; case EnumVar.VTYPE_I2: return Marshal.ReadInt16(); case EnumVar.VTYPE_I4: return Marshal.ReadInt32(); case EnumVar.VTYPE_R4: return Marshal.PtrToStructure<float>(); case EnumVar.VTYPE_R8: return Marshal.PtrToStructure<double>(); case EnumVar.VTYPE_BOOL:return Marshal.ReadByte()!=0; case EnumVar.VTYPE_I1: return (sbyte)Marshal.ReadByte(); case EnumVar.VTYPE_UI1: return Marshal.ReadByte(); case EnumVar.VTYPE_UI2: return (UInt16)Marshal.ReadInt16(); case EnumVar.VTYPE_UI4: return (UInt32)Marshal.ReadInt32(); case EnumVar.VTYPE_I8: return Marshal.ReadInt64(); case EnumVar.VTYPE_UI8: return (UInt64)Marshal.ReadInt64(); case EnumVar.VTYPE_PWSTR: var str= Marshal.PtrToStringUni(Marshal.ReadIntPtr()); return AutoWrap.(str); case EnumVar.VTYPE_BLOB: = + IntPtr; byte[] res = new byte[Marshal.ReadInt32()]; Marshal.Copy(Marshal.ReadIntPtr(), res,0,res.Length); return res; case EnumVar.VTYPE_DATE: var date= Marshal.PtrToStructure<double>(); return DateTimeHelper.FromOADate(date); case EnumVar.VTYPE_TM: return ConvertTmToDateTime(); } return null; } public static IntPtr IntPtr(string str) { var res = UnicodeEncoding.Unicode.GetBytes(str); IntPtr = AutoWrap.(res.Length + 2); Marshal.Copy(res, 0, , res.Length); Marshal.WriteInt16( + res.Length, 0); return ; } static void IntPtr(string str, IntPtr ) { Marshal.WriteIntPtr(, IntPtr(str)); IntPtr = + Marshal.SizeOf<IntPtr>(); Marshal.WriteInt32(, str.Length); } static void IntPtr(byte[] value, IntPtr ) { IntPtr = AutoWrap.(value.Length); Marshal.Copy(value, 0, , value.Length); Marshal.WriteIntPtr(, ); IntPtr = + Marshal.SizeOf<IntPtr>(); Marshal.WriteInt32(, value.Length); } public static bool IntPtr(object , IntPtr ) { IntPtr = + 44; int IntPtr = Marshal.SizeOf<IntPtr>(); if ( == null) { Marshal.WriteInt16(, (Int16)EnumVar.VTYPE_NULL); Marshal.WriteInt32(, 0); return true; } EnumVar ; var res = .TryGetValue(.GetType(), out ); if (!res) return false; Marshal.WriteInt16(, (Int16)); switch () { case EnumVar.VTYPE_I2: Marshal.WriteInt16(,(Int16) ); break; case EnumVar.VTYPE_I4: Marshal.WriteInt32(, (Int32)); break; case EnumVar.VTYPE_R4: double val = (double)(float); Marshal.StructureToPtr<double>(val, ,false); Marshal.WriteInt16(, (Int16)EnumVar.VTYPE_R8); break; case EnumVar.VTYPE_R8: Marshal.StructureToPtr<double>((double), , false); break; case EnumVar.VTYPE_BOOL: Marshal.WriteByte(, Convert.ToByte()); break; case EnumVar.VTYPE_I1: Marshal.WriteByte(, Convert.ToByte()); break; case EnumVar.VTYPE_UI1: Marshal.WriteByte(, (byte)); break; case EnumVar.VTYPE_UI2: Marshal.WriteInt16(, Convert.ToInt16()); break; case EnumVar.VTYPE_UI4: Marshal.WriteInt32(, Convert.ToInt32()); break; case EnumVar.VTYPE_I8: Marshal.WriteInt64(, (Int64)); break; case EnumVar.VTYPE_UI8: Marshal.WriteInt64(, Convert.ToInt64()); break; case EnumVar.VTYPE_PWSTR: IntPtr((string), ); break; case EnumVar.VTYPE_BLOB: IntPtr((byte[]), ); break; case EnumVar.VTYPE_DATE: Marshal.StructureToPtr<double>(((DateTime)).ToOADate(), , false); break; case EnumVar.VTYPE_AutoWrap: IntPtr(((AutoWrap)).(), ); Marshal.WriteInt16(, (Int16)EnumVar.VTYPE_PWSTR); break; } return true; } }
void TestCallMethod(NetObjectToNative::ManagedDomainLoader* mD, long Target) { tVariant Params[4]; tVariant RetVal; tVariant* paParams = Params; typedef std::chrono::high_resolution_clock Clock; auto start = Clock::now(); long r = 0; for (int i = 0; i < 1000000; i++) { paParams->lVal = i; paParams->vt = VTYPE_I4; mD->pCallAsFunc(Target, L"", &RetVal, paParams, 1); r += RetVal.lVal; r %= 1 << 30; } auto finish = Clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count() / 1000000000.0; wprintf_s(L"Tme=: %.2f second\n", elapsed); wprintf_s(L"Eval Value=: %d \n", r); } long GetTarget(tVariant* CurParam) { wchar_t* curstr = CurParam->pwstrVal; curstr += 13; wstring temp = curstr; return stol(temp); } int main() { setlocale(0, ""); // Core CLR // // coreclr.dll NetObjectToNative::ManagedDomainLoader* mD = NetObjectToNative::ManagedDomainLoader::InitManagedDomain(L"c:\\Program Files\\DNX\\runtimes\\dnx-coreclr-win-x86.1.0.0-rc1-update1\\bin\\", L"", L""); if (!mD) return 0; tVariant Params[4]; tVariant RetVal; tVariant* paParams = Params; paParams->vt = VTYPE_PWSTR; paParams->pwstrVal = L"System.Text.StringBuilder"; cout << "Press Key"; cin.get(); // 0 bool res = mD->pCallAsFunc(0, L"", &RetVal, paParams, 1); if (!res) return 0; // 1 // 12 . long // // BLOB // ref ; long Target = GetTarget(&RetVal); // wprintf_s(L"index : %d\n", Target); // . . delete[] RetVal.pstrVal; paParams->vt = VTYPE_PWSTR; paParams->pwstrVal = L" "; // 0 void , res = mD->pCallAsFunc(Target, L"Append", 0, paParams, 1); res = mD->pCallAsFunc(Target, L"ToString", &RetVal, paParams, 0); wprintf_s(L"ToString() : %s\n", RetVal.pwstrVal); delete[] RetVal.pstrVal; paParams->vt = VTYPE_I4; paParams->lVal = 40; res = mD->pSetPropVal(Target, L"Capacity", paParams); res = mD->pGetPropVal(Target, L"Capacity", &RetVal); wprintf_s(L"Capacity : %d\n", RetVal.lVal); // if (!mD->pGetPropVal(Target, L" ", &RetVal)) wprintf_s(L" : %s\n", L" "); // . GC mD->pDeleteObject(Target); // paParams->vt = VTYPE_PWSTR; paParams->pwstrVal = L"System.Text.StringBuilder"; // ID typeof(System.Text.StringBuilder) res = mD->pCallAsFunc(0, L"", &RetVal, paParams, 1); //paParams[0] = RetVal; // ID typeof(System.Text.StringBuilder) // RetVal typeof(System.Text.StringBuilder) // paParams[0] = RetVal; wchar_t* ref = RetVal.pwstrVal; // StringBuilder res = mD->pCallAsFunc(0, L"", &RetVal, paParams, 1); // delete[] ref; if (!res) return 0; // paParams[0] = RetVal; res = mD->pCallAsFunc(0, L"", &RetVal, paParams, 1); // paParams->vt = VTYPE_PWSTR; paParams->pwstrVal = L"TestDllForCoreClr., TestDllForCoreClr, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"; auto par2 = paParams; par2++; par2->vt = VTYPE_PWSTR; par2->pwstrVal = L" "; res = mD->pCallAsFunc(0, L"", &RetVal, paParams, 2); long testRef = GetTarget(&RetVal); paParams->vt = VTYPE_I4; paParams->lVal = 3; res = mD->pCallAsFunc(testRef, L"", &RetVal, paParams, 1); wprintf_s(L"input int : %d\n", RetVal.lVal); TestCallMethod(mD, testRef); TestCallMethod(mD, testRef); TestCallMethod(mD, testRef);
Source: https://habr.com/ru/post/304482/
All Articles