Здравствуйте, Serginio1, Вы писали:
Кстати в первоначальном примере ошибка прокралась
СылкаСБ=Врап.Новый("System.Text.StringBuilder","Первая Строка");
//Сообщить(СылкаСБ);
СсылкаCultureInfo=Врап.ПолучитьТип("System.Globalization.CultureInfo");
СсылкаCultureInfo=Врап.Новый(СсылкаCultureInfo,"es-ES");
// Здесь уже СсылкаCultureInfo указывает на объект
//
СultureInfo=СоздатьОбъектПоСсылке(СсылкаCultureInfo);
И СultureInfo это не тип а объект СсылкаCultureInfo,"es-ES");
// Вызываем статический метод
СсылкаInvariantCulture=СultureInfo.InvariantCulture;
он проходит, так как нет проверки на статик.
Я думаю так и оставить. Можно из объекта как в Delphi вызывать и методы объекта и статические
и солнце б утром не вставало, когда бы не было меня
Столкнулся с такой проблемй.
Если Загрузить в 1с CLR
hr = pfnGetCLRRuntimeHost(IID_ICLRRuntimeHost2, (IUnknown**)&pCLRRuntimeHost);
А затем выгрузить и повторно попробовать загрузить. То получаем недопустимую операцию.
Вторая проблема это то, что можно создать только один домен и его нельзя выгружать.
и солнце б утром не вставало, когда бы не было меня
namespace TestDllForCoreClr
{
public class Тестовый
{
public static string Поле = "Статическое поле";
public string СвойствоОбъекта { get; set; }
public Тестовый(string СвойствоОбъекта)
{
this.СвойствоОбъекта = СвойствоОбъекта;
}
public string ПолучитьСтроку()
{
return"Привет из CoreClr";
}
public int ПолучитьЧисло(int число)
{
return число;
}
}
}
И вызов из С++
//Теперь Создадим эклемпляр класса из сторонней сборки
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);
Ну и вызов миллиона нетовской функции
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);
}
Получилось около 3 сек 2.8, на моем i3-2120 3.3 GHz
Может я что делаю не так?
// Сначала хотел закодировать ссылку в byte[]
// Но 1С может передавать в параметрах только булево,дату, числа и строки
Добави вывод типов для дженерик методов
Теперь можно не выводить отдельно метод
// public T ДженерикМетод<V, T>(V param1, T param2, V param3)
Сообщить(Тест.ДженерикМетод(1,"Привет",3));
//
//public V ДженерикМетод2<K, V>(Dictionary<K, V> param1, K param2, V param3)
Словарь= ъНовый("System.Collections.Generic.Dictionary`2[System.Int32,System.String]");
Сообщить(Тест.ДженерикМетод2(Словарь.ПолучитьСсылку(),3,"Привет2"));
// public K ДженерикМетод3<K>(IList<K> param1, int param2, K param3)
List=ъНовый("System.Collections.Generic.List`1[System.String]");
Сообщить(Тест.ДженерикМетод3(List.ПолучитьСсылку(),3,"Привет3"));
и солнце б утром не вставало, когда бы не было меня
Добавил поддержку параметров по умолчанию
// Тест вызова метода с параметрами по умолчанию
//public static int OptionalParam(int x, int y, int z = 5, int s = 4,string str="Привет")
// {
// return x + y + z + s;
// }
Сообщить("OptionalParam(int x, int y)="+Тестовый.OptionalParam(1,2));
Сообщить("OptionalParam(int x, int y, int z = 5)="+Тестовый.OptionalParam(1,2,3));
Сообщить("OptionalParam(int x, int y, int z = 5, int s,string str)="+Тестовый.OptionalParam(1,2,3,4,"ХаХа"));
Теперь думаю прикрутить методы расширению.
Можно к каждому типу прикрутить типы реализующих расширения.
Поиск провести по типу и сборкам. Может есть какие то другие решения?
и солнце б утром не вставало, когда бы не было меня
Прошу совета по блокировкам. Есть такая конструкция для хранения объектов одного типа.
public struct ЭлементХранилища
{
internal AutoWrap Объект;
internal int Next;
internal ЭлементХранилища(AutoWrap Объект)
{
this.Объект = Объект;
Next = -1;
}
internal ЭлементХранилища(AutoWrap Объект, int next)
{
this.Объект = Объект;
Next = next;
}
}
internal class ХранилищеОбъектов
{
const int НачальноеКоличествоЭлементов = 2;
ЭлементХранилища[] Элементы = new ЭлементХранилища[НачальноеКоличествоЭлементов];
int КоличествоЭлементов = 0;
int РазмерМассива = НачальноеКоличествоЭлементов;
int FirstDeleted = -1;
static SpinLock sl = new SpinLock();
public int Add(AutoWrap Объект)
{
var элемент = new ЭлементХранилища(Объект);
var gotLock = false;
try
{
sl.Enter(ref gotLock);
if (FirstDeleted == -1)
{
return AddInArray(элемент);
}
else
{
int newPos = FirstDeleted;
FirstDeleted = Элементы[newPos].Next;
Элементы[newPos] = элемент;
return newPos;
}
}
finally
{
if (gotLock) sl.Exit();
}
}
int AddInArray(ЭлементХранилища Элемент)
{
if (КоличествоЭлементов == РазмерМассива)
{
var temp = new ЭлементХранилища[РазмерМассива * 2];
Array.Copy(Элементы, 0, temp, 0, Элементы.Length);
Элементы = temp;
РазмерМассива = Элементы.Length;
}
Элементы[КоличествоЭлементов] = Элемент;
var res = КоличествоЭлементов;
КоличествоЭлементов++;
return res;
}
public void RemoveKey(int Pos)
{
var элементы = Элементы;
// Первый элемнт никогда не удаляем.if (Pos > 0 && Pos < элементы.Length && элементы[Pos].Объект != null)
{
var gotLock = false;
try
{
sl.Enter(ref gotLock);
var Элемент = new ЭлементХранилища(null, FirstDeleted);
Элементы[Pos] = Элемент;
FirstDeleted = Pos;
}
finally
{
if (gotLock) sl.Exit();
}
}
}
public AutoWrap GetValue(int Pos)
{
// По идее для получения элемента не нужно никаких блокировок
// Получает текущий массив элеменовvar элементы = Элементы;
if (!(Pos > -1 && Pos < элементы.Length && элементы[Pos].Объект != null))
return null;
return элементы[Pos].Объект;
}
}
Основное изменение массива происходит только при изменении размера массива
if (КоличествоЭлементов == РазмерМассива)
{
var temp = new ЭлементХранилища[РазмерМассива * 2];
Array.Copy(Элементы, 0, temp, 0, Элементы.Length);
Элементы = temp;
РазмерМассива = Элементы.Length;
}
Доступ к элементам массива по идее можно делать без блокировок
public AutoWrap GetValue(int Pos)
{
// По идее для получения элемента не нужно никаких блокировок
// Получает текущий массив элементовvar элементы = Элементы;
if (!(Pos > -1 && Pos < элементы.Length && элементы[Pos].Объект != null))
return null;
return элементы[Pos].Объект;
}
и солнце б утром не вставало, когда бы не было меня
Суть такая из натива вызываем статические методы .Net библиотеки.
Под 32 разрядными dll и exe все прекрасно.
Скомпилировал под 64 разрядное. Если запускать из экзешника
То все нормально. Но если из 64 разрядной 1С 8.3.9
Выдает ошибку
Необработанное исключение по адресу 0x00007FFD76FB8528 (ucrtbase.dll) в 1cv8.exe: Недопустимый параметр был передан функции, для которой недопустимые параметры вызывают неустранимую ошибку.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S> Суть такая из натива вызываем статические методы .Net библиотеки. S>Под 32 разрядными dll и exe все прекрасно.
S>Скомпилировал под 64 разрядное. Если запускать из экзешника S>То все нормально. Но если из 64 разрядной 1С 8.3.9
Библиотека времени выполнения C (CRT)
Общие изменения
•Двоичные файлы, полученные в результате рефакторинга
Был осуществлен рефакторинг библиотеки CRT, в результате чего она была разделена на два разных двоичных файла — универсальный CRT (ucrtbase), который содержит большинство стандартных функциональных возможностей, и библиотеку времени выполнения VC (vcruntime140), которая содержит функции, связанные с компилятором, такие как обработка исключений и встроенные функции. В случае использования параметров проекта по умолчанию это изменение вас не затронет, так как компоновщик будет автоматически использовать новые библиотеки по умолчанию. Если вы установили для свойства Игнорировать все стандартные библиотекикомпоновщика в проекте значение Да или используете параметр компоновщика /NODEFAULTLIB в командной строке, необходимо обновить список библиотек (в свойстве Дополнительные зависимости), чтобы включить в него новые подвергнутые рефакторингу библиотеки. Замените старую библиотеку CRT (libcmt.lib, libcmtd.lib, msvcrt.lib, msvcrtd.lib) эквивалентными подвергнутыми рефакторингу библиотеками. Для каждой из двух подвергнутых рефакторингу библиотек существует статическая (.lib) и динамическая (.dll) версии, а также версия выпуска (без суффикса) и отладочная версия (с суффиксом "d"). Динамические версии имеют библиотеку импорта, с которой выполняется связь. Рефакторингу подвергнуты две библиотеки: универсальная CRT (а именно ucrtbase.dll или ucrtbase.lib, ucrtbased.dll или ucrtbased.lib) и библиотека времени выполнения VC — libvcruntime.lib, libvcruntime.dll, libvcruntimed.lib и libvcruntimed.dll. См. раздел Особенности библиотеки CRT.
и солнце б утром не вставало, когда бы не было меня
Re[2]: Ошибка ucrtbase.dll Недопустимый параметр был передан
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S> Суть такая из натива вызываем статические методы .Net библиотеки. S>Под 32 разрядными dll и exe все прекрасно.
S>Скомпилировал под 64 разрядное. Если запускать из экзешника S>То все нормально. Но если из 64 разрядной 1С 8.3.9
Вот Стек
ucrtbase.dll!_invoke_watson() Нет данных
ucrtbase.dll!_invalid_parameter() Нет данных
ucrtbase.dll!_invalid_parameter_noinfo() Нет данных
ucrtbase.dll!_setmode() Нет данных
clrjit.dll!jitStartup() Нет данных
coreclr.dll!EEJitManager::SetCpuInfo(void) Нет данных
coreclr.dll!EEJitManager::LoadJIT(void) Нет данных
coreclr.dll!UnsafeJitFunction(class MethodDesc *,class COR_ILMETHOD_DECODER *,unsigned long,unsigned long,unsigned long *) Нет данных
coreclr.dll!MethodDesc::MakeJitWorker(class COR_ILMETHOD_DECODER *,unsigned long,unsigned long) Нет данных
coreclr.dll!MethodDesc::DoPrestub(class MethodTable *) Нет данных
coreclr.dll!PreStubWorker() Нет данных
coreclr.dll!ThePreStub() Нет данных
coreclr.dll!UMThunkStub() Нет данных
> AddInNetObjectToNative64.dll!NetObjectToNative::ManagedDomainLoader::CreateManagedDomain(NetObjectToNative::CoreClrStartParams * pCoreClrStartupParams)Строка 128 C++
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S> Суть такая из натива вызываем статические методы .Net библиотеки. S>Под 32 разрядными dll и exe все прекрасно.
S>Скомпилировал под 64 разрядное. Если запускать из экзешника S>То все нормально. Но если из 64 разрядной 1С 8.3.9
Можно ли под машиной запустить Windows и Linux. Под Windows считывать данные и передавать их в приложения под Linux по TCP/IP
Под многое оборудование для Linux нет драйверов. Но вот хотел узнать про виртуальные машины. Можно держать Linux и Windows и обмениваться по TCP/IP.
Сейчас пишу статью по кроосплатформенному применению .Net Core в 1С и обмену по Tcp/IP между различными устройствами.И нужны примеры применения
и солнце б утром не вставало, когда бы не было меня