Micropython User Module: Class Prints Initialized Data Even If Attributes Have Changed - c++

Here's a visual representation of the problem from the front end. Notice that the output from printing the class does not change even if the attributes do, yet I get the proper value from printing the attributes directly.
import bitbanglab as bbl
class Entity(bbl.Entity):
def __init__(self):
super().__init__(bytearray([0x0F]), 1, 1, 2, 2, 8, 2)
print(self) #Entity(x:1, y:1, width:2, height:2, scale:8, len:1, pal:2)
self.x = 50
self.y = 20
self.width = 50
self.height= 60
self.scale = 10
self.len = 200
self.pal = 14
print(self) #Entity(x:1, y:1, width:2, height:2, scale:8, len:1, pal:2)
print(self.x) #50
print(self.y) #20
Entity()
Print Method
STATIC void Entity_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
bitbanglab_Entity_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_printf(print, "Entity(x:%u, y:%u, width:%u, height:%u, scale:%u, len:%u, pal:%u)", self->x, self->y, self->width, self->height, self->scale, self->len, self->pal);
}
get/set attributes
STATIC void Entity_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
bitbanglab_Entity_obj_t *self = MP_OBJ_TO_PTR(self_in);
if (dest[0] == MP_OBJ_NULL) {
if (attr == MP_QSTR_x)
dest[0] = mp_obj_new_int(self->x);
else if(attr == MP_QSTR_y)
dest[0] = mp_obj_new_int(self->y);
else if(attr == MP_QSTR_width)
dest[0] = mp_obj_new_int(self->width);
else if(attr == MP_QSTR_height)
dest[0] = mp_obj_new_int(self->height);
else if(attr == MP_QSTR_scale)
dest[0] = mp_obj_new_int(self->scale);
else if(attr == MP_QSTR_len)
dest[0] = mp_obj_new_int(self->len);
else if(attr == MP_QSTR_pal)
dest[0] = mp_obj_new_int(self->pal);
} else {
if (attr == MP_QSTR_x)
self->x = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_y)
self->y = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_width)
self->width = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_height)
self->height = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_scale)
self->scale = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_len)
self->len = mp_obj_get_int(dest[1]);
else if (attr == MP_QSTR_pal)
self->pal = mp_obj_get_int(dest[1]);
dest[0] = MP_OBJ_NULL;
}
}
Class Type
const mp_obj_type_t bitbanglab_Entity_type = {
{ &mp_type_type },
.name = MP_QSTR_bitbanglab,
.print = Entity_print,
.make_new = Entity_make_new,
.locals_dict = (mp_obj_dict_t*)&Entity_locals_dict,
.attr = Entity_attr,
};
Class Object
typedef struct _bitbanglab_Entity_obj_t {
mp_obj_base_t base;
uint8_t *bitmap;
uint16_t len;
uint16_t x;
uint16_t y;
uint16_t width;
uint16_t height;
uint8_t scale;
uint8_t pal;
} bitbanglab_Entity_obj_t;
Class
The class doesn't have any methods yet. The locals_dict_table for it is empty.
mp_obj_t Entity_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 7, 7, true);
//make self
bitbanglab_Entity_obj_t *self = m_new_obj(bitbanglab_Entity_obj_t);
self->base.type = &bitbanglab_Entity_type;
//arguments
enum { ARG_bitmap, ARG_x, ARG_y, ARG_width, ARG_height, ARG_scale, ARG_pal};
//get buffer
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_bitmap], &bufinfo, MP_BUFFER_RW);
//properties
self->bitmap = (uint8_t *)bufinfo.buf;
self->len = bufinfo.len;
self->x = mp_obj_get_int(args[ARG_x]);
self->y = mp_obj_get_int(args[ARG_y]);
self->width = mp_obj_get_int(args[ARG_width]);
self->height = mp_obj_get_int(args[ARG_height]);
self->scale = mp_obj_get_int(args[ARG_scale]);
self->pal = mp_obj_get_int(args[ARG_pal]);
return MP_OBJ_FROM_PTR(self);
}

I realized the problem. I was subclassing my user-module-defined class, and the values I was setting were not the ones on the super. If I instantiate the Entity class without a subclass and change the attributes, printing the class reflects those changes. Now my new problem is figuring out how to reach the super's attributes from a subclass. I'll update this answer to be stronger when I figure it all out.

Related

Why would vkCreateSwapchainKHR result in an access violation at 0?

I'm trying to learn Vulkan by following the great tutorials from vulkan-tutorial.com but I'm having some trouble at the point where I must create the swap chain. As stated in the title, the vkCreateSwapchainKHR creates the following error: Access violation executing location 0x0000000000000000.
The tutorial suggest this might be a conflict with the steam overlay. This is not the case for me as copying the whole code from the tutorial works.
I'm trying to figure out what went wrong with my code and to learn how to debug such issues as I will not have a reference code in the future. The incriminated line looks this:
if (vkCreateSwapchainKHR(device, &swapChainCreateInfo, nullptr, &swapChain) != VK_SUCCESS) {
throw std::runtime_error("Could not create swap chain");
}
I setup a breakpoint at this line to compare the values of the arguments in my code with the values from the reference code. As far as I can tell, there is no difference. (The adresses of course are different)
Where should I look for a problem in my code? The variable swapChain is a NULL as expected. A wrongly formed swapChainCreateInfo should not make vkCreateSwapchainKHR crash. It would merely make it return something that is not VK_SUCCESS. And device was created without problem:
if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
throw std::runtime_error("Failed to create logical device");
}
EDIT - I am using the validation layer VK_LAYER_LUNARG_standard_validation and my createInfo setup is the following.
// Useful functions and structures
VkPhysicalDevice physicalDevice;
VkSurfaceKHR surface;
VkSwapchainKHR swapChain;
struct QueueFamilyIndices {
std::optional<uint32_t> graphicsFamily;
std::optional<uint32_t> presentationFamily;
bool isComplete() {
return graphicsFamily.has_value() && presentationFamily.has_value();
}
};
struct SwapChainSupportDetails {
VkSurfaceCapabilitiesKHR surfaceCapabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentModes;
};
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice physicalDevice) {
SwapChainSupportDetails swapChainSupportDetails;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &swapChainSupportDetails.surfaceCapabilities);
uint32_t formatCount = 0;
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr);
if (formatCount != 0) {
swapChainSupportDetails.formats.resize(formatCount);
vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, swapChainSupportDetails.formats.data());
}
uint32_t presentModeCount = 0;
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, nullptr);
if (presentModeCount != 0) {
swapChainSupportDetails.presentModes.resize(presentModeCount);
vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, swapChainSupportDetails.presentModes.data());
}
return swapChainSupportDetails;
}
VkSurfaceFormatKHR chooseSwapChainSurfaceFormat(const std::vector<VkSurfaceFormatKHR> & availableFormats) {
if (availableFormats.size() == 1 && availableFormats[0].format == VK_FORMAT_UNDEFINED) {
return { VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
}
for (const auto & availableFormat : availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
return availableFormat;
}
}
return availableFormats[0];
}
VkPresentModeKHR chooseSwapChainPresentMode(const std::vector<VkPresentModeKHR> & availablePresentModes) {
VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
for (const auto & availablePresentMode : availablePresentModes) {
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
return availablePresentMode;
}
else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
bestMode = availablePresentMode;
}
}
return bestMode;
}
VkExtent2D chooseSwapChainExtent2D(const VkSurfaceCapabilitiesKHR & surfaceCapabilities) {
if (surfaceCapabilities.currentExtent.width != std::numeric_limits<uint32_t>::max()) {
return surfaceCapabilities.currentExtent;
}
else {
VkExtent2D actualExtent = { WIDTH, HEIGHT };
actualExtent.width = std::max(std::min(surfaceCapabilities.maxImageExtent.width, actualExtent.width), surfaceCapabilities.minImageExtent.width);
actualExtent.height = std::max(std::min(surfaceCapabilities.maxImageExtent.height, actualExtent.height), surfaceCapabilities.minImageExtent.height);
return actualExtent;
}
}
// Swap Chain creation code
SwapChainSupportDetails swapChainSupportDetails = querySwapChainSupport(physicalDevice);
VkSurfaceFormatKHR surfaceFormat = chooseSwapChainSurfaceFormat(swapChainSupportDetails.formats);
VkPresentModeKHR presentMode = chooseSwapChainPresentMode(swapChainSupportDetails.presentModes);
VkExtent2D extent = chooseSwapChainExtent2D(swapChainSupportDetails.surfaceCapabilities);
uint32_t imageCount = swapChainSupportDetails.surfaceCapabilities.minImageCount + 1;
if (swapChainSupportDetails.surfaceCapabilities.maxImageCount > 0 && imageCount > swapChainSupportDetails.surfaceCapabilities.maxImageCount) {
imageCount = swapChainSupportDetails.surfaceCapabilities.minImageCount;
}
VkSwapchainCreateInfoKHR swapChainCreateInfo = {};
swapChainCreateInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
swapChainCreateInfo.surface = surface;
swapChainCreateInfo.minImageCount = imageCount;
swapChainCreateInfo.imageFormat = surfaceFormat.format;
swapChainCreateInfo.imageColorSpace = surfaceFormat.colorSpace;
swapChainCreateInfo.imageExtent = extent;
swapChainCreateInfo.imageArrayLayers = 1;
swapChainCreateInfo.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
QueueFamilyIndices familyIndices = findQueueFamilies(physicalDevice);
uint32_t queueFamilyIndices[] = { familyIndices.graphicsFamily.value(), familyIndices.presentationFamily.value() };
if (familyIndices.graphicsFamily != familyIndices.presentationFamily) {
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
swapChainCreateInfo.queueFamilyIndexCount = 2;
swapChainCreateInfo.pQueueFamilyIndices = queueFamilyIndices;
}
else {
swapChainCreateInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
swapChainCreateInfo.queueFamilyIndexCount = 0;
swapChainCreateInfo.pQueueFamilyIndices = nullptr;
}
swapChainCreateInfo.preTransform = swapChainSupportDetails.surfaceCapabilities.currentTransform;
swapChainCreateInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
swapChainCreateInfo.presentMode = presentMode;
swapChainCreateInfo.clipped = VK_TRUE;
swapChainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
if (vkCreateSwapchainKHR(device, &swapChainCreateInfo, nullptr, &swapChain) != VK_SUCCESS) {
throw std::runtime_error("Could not create swap chain");
}
I get the resulting structure:
Well, when creating the logical device one needs to set enabledExtensionCount to the actual number of required extensions and not 0 if one expects extensions to work. In my case, it was a simple edit failure. Here is the gem in my code:
createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
createInfo.enabledExtensionCount = 0;
I figured it out by replacing every function from my code by the ones from the reference code until it worked. I'm a bit disappointed that the validation layers didn't catch this. Did I set them wrong? Is this something they should be catching?
EDIT: As pointed out by LIANG LIU, here is the initialization for deviceExtensions:
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME
};
Enable VK_KHR_SWAPCHAIN_EXTENSION_NAME when creating VkDevice
void VKRenderer::createVkLogicalDevice()
{
// device extensions
vector<const char*>::type deviceExtensionNames = { VK_KHR_SWAPCHAIN_EXTENSION_NAME };
// priorities
float queuePrioritys[2] = { 1.f, 1.f};
// graphics queue
VkDeviceQueueCreateInfo queueCreateInfos;
queueCreateInfos.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueCreateInfos.pNext = nullptr;
queueCreateInfos.queueFamilyIndex = getGraphicsQueueFamilyIndex();
queueCreateInfos.queueCount = 1;
queueCreateInfos.pQueuePriorities = &queuePrioritys[0];
// device features
VkPhysicalDeviceFeatures deviceFeatures = {};
VkDeviceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.pQueueCreateInfos = &queueCreateInfos;
createInfo.queueCreateInfoCount = 1;
createInfo.pEnabledFeatures = &deviceFeatures;
createInfo.enabledExtensionCount = deviceExtensionNames.size();
createInfo.ppEnabledExtensionNames = deviceExtensionNames.data();
// create logical device and retrieve graphics queue
if (VK_SUCCESS == vkCreateDevice(m_vkPhysicalDevice, &createInfo, nullptr, &m_vkDevice))
{
vkGetDeviceQueue(m_vkDevice, getGraphicsQueueFamilyIndex(), 0, &m_vkGraphicsQueue);
vkGetDeviceQueue(m_vkDevice, getPresentQueueFamilyIndex(), 0, &m_vkPresentQueue);
}
else
{
EchoLogError("Failed to create vulkan logical device!");
}
}
It looks like you are calling vkCreateDevice at the end of your code segment for creating the swapchain and passing in the VkSwapchainCreateInfo into it. Perhaps you want to call vkCreateSwapchainKHR instead, like:
if (vkCreateSwapchainKHR(device, &swapChainCreateInfo, nullptr, &swapChain) !=
VK_SUCCESS) {
throw std::runtime_error("failed to create swap chain");
}
If you are actually calling vkCreateSwapchainKHR, could you edit your question to indicate this?

Return of 2 identical userdata

I want new and at to return the same userdata, please tell me how to do it
example code that I use
struct SCheckpoint {
rage::ICheckpoint* r_Checkpoint;
SCheckpoint(rage::ICheckpoint* checkpoint) {
r_Checkpoint = checkpoint;
}
int GetId() const {
return r_Checkpoint->GetId();
}
}
int createCheckpoint(lua_State* state) {
rage::ICheckpoint* checkpoint = RaluCore::getInstance().getMultiPlayer()->GetCheckpointPool().New(model, vec, vec, radius, color, defaultShow, dimension);
SCheckpoint* scriptCheckpoint = new SCheckpoint(checkpoint);
checkpoint->External(scriptCheckpoint);
push(state, scriptCheckpoint);
return 1;
}
int atCheckpoint(lua_State* state) {
LuaRef ref = LuaRef::fromStack(state, 1);
rage::ICheckpoint* checkpoint = RaluCore::getInstance().getMultiPlayer()->GetCheckpointPool().GetAt(ref);
SCheckpoint* scriptCheckpoint = checkpoint->External<SCheckpoint>();
push (state, scriptCheckpoint);
return 1;
}
getGlobalNamespace(state)
.beginClass<SCheckpoint>("SCheckpoint")
.addProperty("id", &SCheckpoint::GetId)
.endClass()
.addCFunction("at", &atCheckpoint)
.addCFunction("new", &createCheckpoint);
userdata has different addresses, because of this new != at
local createdCheckpoint = mp.checkpoints.new()
print(createdCheckpoint.id)
local gettedCheckpoint = mp.checkpoints.at(0)
print(gettedCheckpoint.id)
print(createdCheckpoint, gettedCheckpoint, createdCheckpoint == gettedCheckpoint)
returned -
0
0
userdata: 0x34a8c320 userdata: 0x34a8d5b0 false

QSpinBox with Unsigned Int for Hex Input

There are a variety of questions written here about QSpinBox's limitation of using an int as its datatype. Often people want to display larger numbers. In my case, I want to be able to show an unsigned 32bit integer in hexadecimal. This means I'd like my range to be [0x0, 0xFFFFFFFF]. The largest a normal QSpinBox can go is 0x7FFFFFFF. Answering my own question here, the solution I came up with is to simply force the int to be treated like an unsigned int, by reimplementing the relevant display and validation functions.
The result is pretty simple, and it works well. Sharing here in case anyone else can benefit from this. It has a 32bit mode and a 16bit mode.
class HexSpinBox : public QSpinBox
{
public:
HexSpinBox(bool only16Bits, QWidget *parent = 0) : QSpinBox(parent), m_only16Bits(only16Bits)
{
setPrefix("0x");
setDisplayIntegerBase(16);
if (only16Bits)
setRange(0, 0xFFFF);
else
setRange(INT_MIN, INT_MAX);
}
unsigned int hexValue() const
{
return u(value());
}
void setHexValue(unsigned int value)
{
setValue(i(value));
}
protected:
QString textFromValue(int value) const
{
return QString::number(u(value), 16).toUpper();
}
int valueFromText(const QString &text) const
{
return i(text.toUInt(0, 16));
}
QValidator::State validate(QString &input, int &pos) const
{
QString copy(input);
if (copy.startsWith("0x"))
copy.remove(0, 2);
pos -= copy.size() - copy.trimmed().size();
copy = copy.trimmed();
if (copy.isEmpty())
return QValidator::Intermediate;
input = QString("0x") + copy.toUpper();
bool okay;
unsigned int val = copy.toUInt(&okay, 16);
if (!okay || (m_only16Bits && val > 0xFFFF))
return QValidator::Invalid;
return QValidator::Acceptable;
}
private:
bool m_only16Bits;
inline unsigned int u(int i) const
{
return *reinterpret_cast<unsigned int *>(&i);
}
inline int i(unsigned int u) const
{
return *reinterpret_cast<int *>(&u);
}
};
If you don't need full 32 bits you can do it very simply like this:
#pragma once
#include <QSpinBox>
class PaddedSpinBox : public QSpinBox
{
public:
PaddedSpinBox(QWidget *parent = 0) : QSpinBox(parent)
{
}
protected:
QString textFromValue(int value) const override
{
// Pad to the width of maximum().
int width = QString::number(maximum(), displayIntegerBase()).size();
return QString("%1").arg(value, width, displayIntegerBase(), QChar('0')).toUpper();
}
};
In the form designer (or whatever) then you just set:
prefix: 0x
displayIntegerBase: 16
maximum: 255 (or whatever)
If you need full 32 bits you will have to employ casting tricks, or maybe just use a line edit.
I came up with the same problem but using PyQt so I could not avoid the range checking that Qt was doing in C under the hood.
The workaround was to use a QDoulbeSpinbox and to cast the value to an int in textFromValue.
Here is my code (it also implements a right click menu to change the display base):
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future_builtins import *
import re
import sys
from PyQt4.QtCore import (QRegExp, Qt)
from PyQt4.QtGui import (QApplication, QRegExpValidator, QDoubleSpinBox)
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
from PyQt4 import QtCore, QtGui
# Regex adapted from Mark Pilgrim's "Dive Into Python" book
class QHexSpinBox(QDoubleSpinBox):
def __init__(self, parent=None):
super(QHexSpinBox, self).__init__(parent)
self.mode = 'dec'
self.setContextMenuPolicy(Qt.CustomContextMenu);
regex = QRegExp("[x0-9A-Fa-f]{1,8}")
regex.setCaseSensitivity(Qt.CaseInsensitive)
self.hexvalidator = QRegExpValidator(regex, self)
regex = QRegExp("[0-9]{1,10}")
regex.setCaseSensitivity(Qt.CaseInsensitive)
self.decvalidator = QRegExpValidator(regex, self)
regex = QRegExp("[b0-1]{1,64}")
regex.setCaseSensitivity(Qt.CaseInsensitive)
self.binvalidator = QRegExpValidator(regex, self)
self.setRange(1, 999999)
self.connect(self,SIGNAL("customContextMenuRequested(QPoint)"),
self,SLOT("contextMenuRequested(QPoint)"))
#pyqtSlot(QtCore.QPoint)
def contextMenuRequested(self,point):
menu = QtGui.QMenu()
hex = menu.addAction("Hex")
dec = menu.addAction("Dec")
bin = menu.addAction("Bin")
self.connect(hex,SIGNAL("triggered()"),
self,SLOT("hex()"))
self.connect(dec,SIGNAL("triggered()"),
self,SLOT("dec()"))
self.connect(bin,SIGNAL("triggered()"),
self,SLOT("bin()"))
menu.exec_(self.mapToGlobal(point))
#pyqtSlot()
def hex(self):
self.mode = 'hex'
self.setValue(self.value())
#pyqtSlot()
def dec(self):
self.mode = 'dec'
self.setValue(self.value())
#pyqtSlot()
def bin(self):
self.mode = 'bin'
self.setValue(self.value())
def validate(self, text, pos):
if self.mode == 'hex':
return self.hexvalidator.validate(text, pos)
if self.mode == 'dec':
return self.decvalidator.validate(text, pos)
if self.mode == 'bin':
return self.binvalidator.validate(text, pos)
def valueFromText(self, text):
if self.mode == 'hex':
return int(unicode(text), 16)
elif self.mode == 'dec':
return int(unicode(text))
elif self.mode == 'bin':
return int(unicode(text), 2)
def textFromValue(self, value):
value = int(value)
if self.mode == 'hex':
return hex(value)
elif self.mode == 'dec':
return str(value)
elif self.mode =='bin':
return "0b{0:b}".format(value)
I know this is an old answer but came here from google. Here is my solution with pyside 1.2.4 based somewhat off of Techniquab's solution but doesn't have the integer overflow issue:
from PySide import QtCore, QtGui
from numpy import base_repr
from PySide.QtGui import QRegExpValidator
class QBaseSpinBox(QtGui.QAbstractSpinBox):
valueChanged = QtCore.Signal(int)
_value = 0
default_value = 0
base = 10
def __init__(self, parent=None):
self.setRange(None, None)
QtGui.QAbstractSpinBox.__init__(self, parent)
self.set_base(self.base)
self.lineEdit().setValidator(QRegExpValidator(self))
self.default_value = self.value()
self.lineEdit().textChanged.connect(self.textChanged)
self.lineEdit().setContextMenuPolicy(QtCore.Qt.CustomContextMenu);
self.lineEdit().customContextMenuRequested.connect(self.contextMenuRequested)
#QtCore.Slot()
def contextMenuRequested(self, point):
menu = self.lineEdit().createStandardContextMenu() #QtGui.QMenu()
actionDefault = menu.addAction("&Set Default Value of %s" % self.textFromValue(self.default_value),
shortcut=QtCore.Qt.CTRL | QtCore.Qt.Key_D) #QtGui.QKeySequence("Ctrl+D")))
menu.insertSeparator(actionDefault)
actionDefault.triggered.connect(self.menuActionDefault_triggered)
menu.exec_(self.mapToGlobal(point))
#QtCore.Slot()
def menuActionDefault_triggered(self):
self.setValue(self.default_value)
def value(self):
return self._value
def setValue(self, value):
if self.validate(value) == QtGui.QValidator.Invalid:
self.setValue(self._value)
return
changed = False
if self._value != value:
changed = True
self._value = value
self.lineEdit().setText(self.textFromValue(value))
if changed:
self.valueChanged.emit(self._value)
#QtCore.Slot()
def stepBy(self, value):
self.setValue(self._value + value)
QtGui.QAbstractSpinBox.stepBy(self, self._value)
def stepEnabled(self):
return QtGui.QAbstractSpinBox.StepDownEnabled | QtGui.QAbstractSpinBox.StepUpEnabled
#QtCore.Slot()
def textChanged(self, text):
try:
self.setValue(int(text, self.base))
except:
self.setValue(self._value)
def setRange(self, _min, _max):
self.minimum = _min if _min != None else 0
self.maximum = _max if _max != None else 0xFFFFFFFFFFFFFFFF
def validate(self, input):
if not input:
return QtGui.QValidator.Intermediate
try:
try:
value = int(input, self.base)
except TypeError:
value = input
if not (self.minimum <= input <= self.maximum):
raise Exception()
except Exception as ex:
return QtGui.QValidator.Invalid
return QtGui.QValidator.Acceptable
def valueFromText(self, text):
return int(text, self.base)
def textFromValue(self, value):
return base_repr(value, self.base).upper()
def set_default_value(self, value):
self.default_value = int(value)
#self.setValue(self.default_value)
self.set_base(self.base) # Redo the tooltip
def set_base(self, base):
self.base = base
min = self.textFromValue(self.minimum)
max = self.textFromValue(self.maximum)
default = self.textFromValue(self.default_value)
self.lineEdit().setToolTip("Base %d\nRange: %s-%s\nDefault Value: %s" % (self.base, min, max, default))
Thanks #ZX2C4 for the answer. I some modified the class HexSpinBox:
you may set prefix.
you may set max range (in case INT_MAX < maxRange < UINT_MAX there are bugs).
you may disable fill fields 0.
width of fields count auto.
hexspinbox.h
#ifndef HEXSPINBOX_H
#define HEXSPINBOX_H
#include <QSpinBox>
class HexSpinBox : public QSpinBox
{
Q_OBJECT
public:
HexSpinBox(QWidget *parent = nullptr);
unsigned int hexValue() const { return u(value()); }
void setHexValue(unsigned int value) { setValue(i(value)); }
void setRange(unsigned int max);
bool fillField() const { return m_fillField; }
void setFillField(bool fillFieldWidth) { m_fillField = fillFieldWidth; }
protected:
QString textFromValue(int value) const;
int valueFromText(const QString &text) const;
QValidator::State validate(QString &input, int &pos) const;
private:
unsigned int m_maxRange = UINT_MAX;
bool m_fillField = true;
inline unsigned int u(int i) const { return *reinterpret_cast<unsigned int *>(&i); }
inline int i(unsigned int u) const { return *reinterpret_cast<int *>(&u); }
};
#endif // HEXSPINBOX_H
hexspinbox.cpp
#include "hexspinbox.h"
HexSpinBox::HexSpinBox(QWidget *parent) : QSpinBox(parent), m_maxRange(maximum())
{
setDisplayIntegerBase(16);
}
void HexSpinBox::setRange(unsigned int max)
{
m_maxRange = max;
if (m_maxRange <= INT_MAX) {
QSpinBox::setRange(0, int(m_maxRange));
} else {
QSpinBox::setRange(INT_MIN, INT_MAX);
}
}
QString HexSpinBox::textFromValue(int value) const
{
int fillField = 0;
if (m_fillField) {
uint m = m_maxRange;
while (m) {
m >>= 4;
++fillField;
}
}
return QString("%1").arg(u(value), fillField, 16, QLatin1Char('0')).toUpper();
}
int HexSpinBox::valueFromText(const QString &text) const
{
return i(text.toUInt(nullptr, 16));
}
QValidator::State HexSpinBox::validate(QString &input, int &pos) const
{
QString copy(input);
QString pref = prefix();
if (copy.startsWith(pref))
copy.remove(pref);
pos -= copy.size() - copy.trimmed().size();
copy = copy.trimmed();
if (copy.isEmpty())
return QValidator::Intermediate;
input = pref + copy.toUpper();
bool okay;
unsigned int val = copy.toUInt(&okay, 16);
if (!okay || val > m_maxRange)
return QValidator::Invalid;
return QValidator::Acceptable;
}
You can use the class for the range [0x0, 0xFFFFFFFF] :
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
ui->hexspinbox->setRange(UINT_MAX); // or 0xFF =)
ui->hexspinbox->setPrefix("0x");
}

Custom C++ ASP .NET Membership Login

Does anyone know how can I hash the user's password using the salt key provided by the ASP .NET Membership?
I'm developing a C++ Linux application and I have only access to the SQL Server.
Thanks,
Here is the encoding algorithm used by ASP.Net Membership which is written in C#.
It uses System.Security, so you might want to look at MONO if you want to run on Lunix.
Note: I'm not familiar with MONO.
private string EncodePassword(string pass, int passwordFormat, string salt)
{
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
return pass;
byte[] bIn = Encoding.Unicode.GetBytes(pass);
byte[] bSalt = Convert.FromBase64String(salt);
byte[] bRet = null;
if (passwordFormat == 1)
{ // MembershipPasswordFormat.Hashed
HashAlgorithm hm = GetHashAlgorithm();
if (hm is KeyedHashAlgorithm)
{
KeyedHashAlgorithm kha = (KeyedHashAlgorithm)hm;
if (kha.Key.Length == bSalt.Length)
{
kha.Key = bSalt;
}
else if (kha.Key.Length < bSalt.Length)
{
byte[] bKey = new byte[kha.Key.Length];
Buffer.BlockCopy(bSalt, 0, bKey, 0, bKey.Length);
kha.Key = bKey;
}
else
{
byte[] bKey = new byte[kha.Key.Length];
for (int iter = 0; iter < bKey.Length; )
{
int len = Math.Min(bSalt.Length, bKey.Length - iter);
Buffer.BlockCopy(bSalt, 0, bKey, iter, len);
iter += len;
}
kha.Key = bKey;
}
bRet = kha.ComputeHash(bIn);
}
else
{
byte[] bAll = new byte[bSalt.Length + bIn.Length];
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
bRet = hm.ComputeHash(bAll);
}
}
else
{
byte[] bAll = new byte[bSalt.Length + bIn.Length];
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
bRet = EncryptPassword(bAll, _LegacyPasswordCompatibilityMode);
}
return Convert.ToBase64String(bRet);
}
private string GenerateSalt()
{
byte[] buf = new byte[SALT_SIZE];
(new RNGCryptoServiceProvider()).GetBytes(buf);
return Convert.ToBase64String(buf);
}

Object reference not set to an instance Of Object

Good day to all,
Please I need somebody to help me have a look at my codes.I am having this error of** Object reference not set to an instance Of Object**.It appears the error is within this lines of codes
if (_scrollingTimer == null)
{
_scrollingTimer = new Timer()
{
Enabled = false,
Interval = 500,
Tag = (sender as TrackBar).Value
};
but unfortunately I was unable to resolve this error.I would be very glad if somebody could help me out.thank you for the usual support.best regards.
Firstoption.
Below are the remaining part of the codes.
byte[] data = new byte[5];
private Timer _scrollingTimer = null;
private void button3_Click(object sender, EventArgs e)
{
UInt32 numBytesWritten = 0;
data[0] = 1;
myFtdiDevice.Write(data, 1, ref numBytesWritten);
data[0] = 0x6A;
myFtdiDevice.Write(data, 1, ref numBytesWritten);
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
if(!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
UInt32 numBytesWritten = 1;
string dataToWrite = "#0";
if (_scrollingTimer == null)
{
_scrollingTimer = new Timer()
{
Enabled = false,
Interval = 500,
Tag = (sender as TrackBar).Value
};
_scrollingTimer.Tick += (s, ea) =>
{
if (trackBar1.Value == (int)_scrollingTimer.Tag)
{
_scrollingTimer.Stop();
myFtdiDevice.Write(dataToWrite, dataToWrite.Length, ref numBytesWritten);
int percent = (int)(((double)trackBar1.Value / (double)trackBar1.Maximum) * 100);
label2.Text = (percent.ToString()) + "%";
data[0] = Convert.ToByte(percent);
data[1] = 0x6A;
myFtdiDevice.Write(data, 2, ref numBytesWritten);
_scrollingTimer.Dispose();
_scrollingTimer = null;
}
else
{
_scrollingTimer.Tag = trackBar1.Value;
}
};
_scrollingTimer.Start();
}
}
sender is not a TrackBar. Looks like it's probably backgroundWorker1.