Страницы

Поиск по вопросам

суббота, 16 марта 2019 г.

обработка массива пользовательской функцией в perl

Как в функцию передать массив и что то с ним сделать в perl?


Ответ

Можно передавать указатель на массив:
#!perl.exe -w use strict; use utf8;
our @array = qw(Мама мыла Вишну);
sub printArray{ my ($ref) = @_;
for my $element (@$ref) { print "$element
"; } }
printArray(\@array);
См. perldoc perlref

BroadcastReceiver не определяет включённый Bluetooth при включении из области уведомлений

Имеется код:
brEnableBt = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED.equals(action)) { int scanStatus = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, 0); Log.d(TAG, String.valueOf(scanStatus)); if (scanStatus == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { checkBluetooth.setChecked(true); checkBluetooth.setClickable(false); } else { checkBluetooth.setChecked(false); checkBluetooth.setClickable(true); } } } }; IntentFilter edBtBrIntent = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); registerReceiver(brEnableBt, edBtBrIntent);
Он должен отлавливать состояние Bluetooth "включён, видим". Если включать Bluetooth через настройки, то всё нормально. Но если я включаю Bluetooth из области уведомлений, то ничего не случается. В логи ничего не пишется. Зато при отключении записывается статус "отключен" (20). Что с этим делать?


Ответ

После непродолжительного гугления придумал вот такое решение:
brEnableBt = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0); Log.d(TAG, String.valueOf(state)); if (state == BluetoothAdapter.STATE_ON) { adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { checkBluetooth.setChecked(true); checkBluetooth.setClickable(false); } else { checkBluetooth.setChecked(false); checkBluetooth.setClickable(true); } //Toast.makeText(context, "Bluetooth is enabled", Toast.LENGTH_LONG).show(); } else { checkBluetooth.setChecked(false); checkBluetooth.setClickable(true); //Toast.makeText(context, "Bluetooth is disabled", Toast.LENGTH_LONG).show(); } } } };
Решение вроде бы работает. Но есть одно но. При изменении состояния видимости уже включённого блютуза отметка у чекбокса опять же не меняется. UPD: Интересная вещь получается. Если использовать код из вопроса, то он будет работать как раз при изменении видимости включённого блютуза. Если использовать код из моего ответа, то он будет определять видимость при включении блютуза. Следовательно, эти два решения надо совместить. UPD2: Разобрался. Перепробовал разные способы, сработал вот такой: зарегистрировать два разных ресивера на включение и на смену статуса. Правда, похоже, оперативку они будут жрать за милую душу...

В чем разница между bintime() и nanotime()?

В чем разница между nanotime(9) и bintime(9), если возвращаемое значение bintime(struct bintime) можно конвертировать c помощью bintime2timespec в значение nanotime(timespec)?


Ответ

bintime использует структуры с более натуральными полями, арифметика над которыми значительно проще, и потому их использование более эффетивно. Текущие версии ядра и системных утилит используют именно bintime структуры для операций с отметками времени, переводя в други форматы только при необходимости. Грубо говоря, nanotime реализовано через bintime

Как при наличии отладочных символов только своей dll получить её переменные из дампа памяти приложения?

Есть моя DLL библиотека (проект Visual Studio 2013). Ее используют чужие программы. Во время работы этих программ было сохранено несколько полных дампов память процессов этих программ. Я открываю эти дампы в моем Visual Studio проекте. Отладочные символы я имею только для моей DLL. При этом, если во время сохранения дампа исполнялся код одной из функций моей DLL, то видно все символы в исходном коде, место текущего исполнения итд. Но если, исполнялся другой код, я никаких данных не вижу и посмотреть текущее значение переменных моей DLL не могу. Локальные переменные ясное дело недоступны, так как их нет, но и статические данные тоже не видны.
Как просматривать данные моей DLL?


Ответ

Не уверен, можно ли это сделать через студию. Но точно можно через WinDBG:
Открыть дамп. Включить ссылки в выводе:
.prefer_dml 1 Прописать путь к символам:
.sympath+ srv* Загрузить SOS (пусть исправить на соответствующий версии и платформе)
для 4.0:
.loadby sos clr
для <4.0
.loadby sos mscorwks
или по полному пути
.load C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll Найти EEClass для того типа, для которого хочется посмотреть статические поля
> !name2ee mscorlib.dll System.Console Module: 0000064278854000 (mscorlib.dll) Token: 0x000000000200008b MethodTable: 00000642788c8d10 EEClass: 0000064278a271a8 Name: System.Console Посмотреть статические поля:
> !dumpclass 0000064278a271a8 Class Name: System.Console mdToken: 000000000200008b (C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) Parent Class: 00000642788c0c30 Module: 0000064278854000 Method Table: 00000642788c8d10 Vtable Slots: 4 Total Method Slots: 78 Class Attributes: 100181 Abstract, NumInstanceFields: 0 NumStaticFields: d MT Field Offset Type VT Attr Value Name 00000642788f5aa0 40002ae d8 System.IO.TextReader 0 shared static _in
Дальше перемещаться кликами по адресам объектов - в режиме DML по клику будет выполнятся соответствующая команда для дампа объекта.
По настройке WinDBG есть отличный мануал Debugging Managed Code Using the Windows Debugger.

Сохранение RichTextBox в rtf формат

Нужно сохранить RichTextBox в rtf формат. Вроде ничего сложного, но у меня появилась одна проблема. У меня в RichTextBox есть немного текста. Сохраняю в rtf файл:
exRichTextBox1.SaveFile("zzz.rtf", RichTextBoxStreamType.RichText);
Размер полученного файла как и предполагалось несколько килобайт. Но я еще в RichTextBox вставляю картинки.
exRichTextBox1.InsertImage(Image.FromFile("photo1.jpg")); exRichTextBox1.InsertImage(Image.FromFile("photo2.jpg"));
Так же само сохраняю в файл:
exRichTextBox1.SaveFile("zzz.rtf", RichTextBoxStreamType.RichText);
И полученный файл занимает около 25мб. Сами картинки в суме занимают 1,5мб. Пробивал одну картинку на 0,5мб и полученный файл занимает около 10мб. Короче файл в формате rtf занимает памяти в 15-20 раз больше чем должен. В чем может быть проблема?


Ответ

Как я понял размер полученного RTF файла больше, потому что RTF сохраняет изображение в формате WMF (Windows Metafile), несжатый формат, из-за этого и размер такой большой. И единственный способ уменьшить размер файла, это архивировать его в rar/zip. Или сделать вот эти изменение в реестре, и пересохранить RTF файл в ворде. Тогда размер уменьшится в 2 раза. А если RTF файл сохранить в формате docx, то размер уменьшится в 4 раза (у меня так вышло).

Как сохранять и загружать данные в/из кэша при повторном запуске приложения на Android?

Есть полезные ссылки на данную тему? Я так понимаю, что мне нужно будет создать БД на SQlite в приложении, занести туда данные. А вот как дальше действовать? Как мне их отобразить из кэша, а не заново "скачивать"?


Ответ

Из вопроса не ясно какой объем данных (переменных, массивов) необходимо сохранять при выходе из приложения?!
Если данных немного, то можно воспользоваться механизмом: "SharedPreferences":
Назначение переменных для сохранения:
static final String SAVE_USERID = "save_userid"; static final String SAVE_PASSWORD = "save_password"; public static String un = "MyName", pw = "MyPassword";
Метод сохранения:
public void saveSettings() { SharedPreferences.Editor ed = getSharedPreferences("setting",MODE_PRIVATE).edit(); ed.putString(SAVE_USERID, un); ed.putString(SAVE_PASSWORD, pw); ed.commit(); }
Медод восстановления:
public void loadSettings() { un = getSharedPreferences("setting",MODE_PRIVATE).getString(SAVE_USERID, ""); pw = getSharedPreferences("setting",MODE_PRIVATE).getString(SAVE_PASSWORD, ""); }
Если данных много, то необходима работа с БД.

Запись и чтение в файл через pickle

Хочу разобраться с записью/чтением в файл. Есть код:
import pickle result = {'vova':'8', 'stepa': '6', 'primer':'9', 'vovas': '12'} dee = open('dadt.dat','ab') pickle.dump(result,dee) dee.close() dee = open('dadt.dat','rb') der = pickle.load(dee) for i in der: print(i, der[i])
Что я ожидаю от него - выводить то что есть в файле, если меняю список result - дописывать новые значения (проверка на дубли за рамками задачи).
Что получаю - вывод корректно производится один раз, однако при изменении словаря и повторной записи - выводит то же самое, что и в первый раз.
Скажем меняю result на
result = {'vova':'8', 'stepa': '6', 'primer':'9', 'vovas': '12', 'novoe':'12'}
А получаю такой же вывод, как и в первом случае.
Подскажите, что делаю не так?


Ответ

Ваша проблема в том, что вы считываете значение из файла только один раз. pickle не даёт возможности синхронизации файла с переменной, поэтому вам нужно осуществлять это самостоятельно каждый раз.
Также если вы открываете файл на добавление (ключ 'a'), то содержимое переменной запишется в конец файла (т.е. при втором вызове в файле будет записано уже две переменных, при третьем -- три и так далее). Функция pickle.load считывает за один вызов только один объект из файла, поэтому вам придётся вызывать её несколько раз, чтобы добраться до последней сохранённой переменной.
Если я правильно понял вашу задачу, вам не нужно хранить разные состояния вашей переменной, а достаточно только последнего, но обновлённого. Для этого нужно открывать файл на чтение (ключ 'w'), что будет перезаписывать файл каждый раз, когда вы сохраняете обновления вашей переменной.
После этого просто сохраняйте переменную тогда, когда вам нужно учесть её обновления и загружайте их из файла дампа при необходимости синхронизации с записанным в файл состоянием.
import pickle result = {'vova':'8', 'stepa': '6', 'primer':'9', 'vovas': '12'}
# сохраняем словарь в файл with open('dump.dat', 'wb') as dump_out: pickle.dump(result, dump_out)
# загружаем словарь из файла with open('dump.dat', 'rb') as dump_in: der = pickle.load(dump_in)
for key, value in der.items(): print(key, value)
# обновляем словарь result = {'vova':'8', 'stepa': '6', 'primer':'9', 'vovas': '12', 'novoe':'12'}
# снова сохраняем словарь в файл with open('dump.dat', 'wb') as dump_out: pickle.dump(result, dump_out)
# снова загружаем словарь из файла with open('dump.dat', 'rb') as dump_in: der = pickle.load(dump_in)
for key, value in der.items(): print(key, value)
Также обратите внимание на конструкцию with для работы с файлами и на метод .items() у словаря, который возвращает генератор всех пар ключ-значение этого словаря.