Re: .Net Core. Вызов манагед кода из натива
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 16.06.16 11:17
Оценка:
Здравствуйте, Serginio1, Вы писали:



S>Начну с того, что в 1С есть технология Внешних компонент Native API Технология создания внешних компонент Технология создания внешних компонент которые работают как под Windows так и под Linux


Сделал маршалинг из натива в манагед

namespace CoreClrDLL
{

//    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
    };

    public class РаботаСВариантами
    {
      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: return Marshal.PtrToStringUni(Marshal.ReadIntPtr(Элемент));

                case EnumVar.VTYPE_BLOB:
                    текПоз = Элемент + размерIntPtr;
                    byte[] res = new byte[Marshal.ReadInt32(текПоз)];
                    Marshal.Copy(Marshal.ReadIntPtr(Элемент), res,0,res.Length);
                    return res;
            }
            return null;
            }



        }
}



static object[] ПолучитьМассивПараметров(IntPtr МассивПараметров, int РазмерМассива)
        {

            var result = new object[РазмерМассива];
            IntPtr ТекПоз = МассивПараметров;
            for (var i=0; i< result.Length; i++)
            {
                result[i] = РаботаСВариантами.ПолучитьОбъекИзIntPtr(ТекПоз);

                ТекПоз += 48;
            }

            return result;
        }
        public static bool CallAsFunc(int Target, IntPtr ИмяМетодаPtr, IntPtr ReturnValue, IntPtr МассивПараметров,int РазмерМассива)
            {

            string ИмяМетода = Marshal.PtrToStringUni(ИмяМетодаPtr);
            var параметры = ПолучитьМассивПараметров(МассивПараметров, РазмерМассива);
            return true;

        }




На С++

typedef void(STDMETHODCALLTYPE *ManagedCallAsFunc)(const __int32, const wchar_t*, tVariant* pvarRetValue, tVariant* paParams, const __int32  lSizeArray);

ManagedCallAsFunc  pCallAsFunc;

hr = CreateDelegate2(pCLRRuntimeHost, domainId, L"CoreClrDLL", L"CoreClrDLL.Program", L"CallAsFunc", (INT_PTR*)&pCallAsFunc);
    if (FAILED(hr))
    {
        printf_s("Failed to create a delegate to the managed entry point: (%d).\n", hr);

    }
    else
    {
        //(const __int32, const wchar_t*, tVariant* pvarRetValue, tVariant* paParams, const __int32  lSizeArray);
        wchar_t* str = L"Test str from unmanaged";
        tVariant* paParams = new tVariant[4];
        tVariant* paP = paParams;
        paP->vt = VTYPE_I4;
        paP->lVal = 8;

        paP++;

        paP->vt = VTYPE_BOOL;
        paP->lVal = true;

        paP++;
        paP->vt = VTYPE_PWSTR;
        paP->pwstrVal = str;

        byte* pb = new byte[4]; pb[0] = 27; pb[1] = 28; pb[2] = 29; pb[3] = 30;
        paP++;
        paP->vt = VTYPE_BLOB;
        paP->pstrVal = (char*)pb;
        paP->strLen = 4;
        pCallAsFunc(-1, str, 0, paParams, 4);
    }


Вроде нормально отрабатывает
и солнце б утром не вставало, когда бы не было меня
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.