Здравствуйте, 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);
}
Вроде нормально отрабатывает