VB.net API variables - vb.net

I really hope someone can help me with this, I've searched everywhere and can't find anything on the matter.
I've got a SMART card printer that prints plastic cards and I've been given the API to interact with it directly from vb.net, I've managed to execute most of the functions but one of them refers to a
1 COLORREF
and a
1 WCHAR*
variable and I'm clueless as to what they want me to provide.
Below is the structure I've been given for context
01 int SmartComm_DrawBarcode(
02 HSMART hHandle,
03 BYTE page,
04 BYTE panel,
05 int x,
06 int y,
07 int cx,
08 int cy,
09 COLORREF col,
10 RECT* prcArea,
11 const WCHAR* szName,
12 int nSize,
13 const WCHAR* szData,
14 const WCHAR* szPost
15 );
Below is the code that I'm using to execute one of the functions and it works perfectly, I just can't get the barcode working:
1 Dim lclogo As String = "C:\acer\lclogo.png"
2 strImg_ptr = Marshal.StringToHGlobalUni(LunchcardLogo)
3 rcDraws_ptr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(RECT)))
4 If nres = SM_SUCCESS Then
5 nres = SmartComm_DrawImage(hsmart, CByte(PAGE_FRONT), CByte(PANEL_BLACK), 606, 456, 405, 171, strImg_ptr, rcDraws_ptr)
6 End If
7
8 Marshal.FreeHGlobal(strImg_ptr)
9 Marshal.FreeHGlobal(rcDraws_ptr)
*I know that the original structure is in either c# or c++ but I can't for the life of me find the equivalent in vb.net.
Thanks guys.

A COLORREF is basically a 32bit integer value. You can define a struct to interact with it like this (see this link for details):
Structure COLORREF
Public R As Byte
Public G As Byte
Public B As Byte
Public Overrides Function ToString() As String
Return String.Format("({0},{1},{2})", R, G, B)
End Function
End Structure
WCHAR* is a pointer to a wide-character string. So you can use String as its data type and add the MarshalAs attribute:
WCHAR* szName
will be
<MarshalAs(UnmanagedType.LPWStr)> szName As String

Related

Kotlin `toInt()` Two's Complement

I believe FFFFFFFF is -1 because of Two's Complement.
I tried to convert Hex String into Integer, but I got the error.
Here is the code I have tried.
code
// Extension functions
val Int.asByteArray get() =
byteArrayOf(
(this shr 24).toByte(),
(this shr 16).toByte(),
(this shr 8).toByte(),
this.toByte())
val Int.asHex get() = this.asByteArray.asHexUpper
// Main Code
fun main()
{
println((-1).asHex)
println("FFFFFFFF".toInt(16))
}
Result
FFFFFFFF
Exception in thread "main" java.lang.NumberFormatException: For input string: "FFFFFFFF"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
Is this intended? or Is this error?
If this is intended, then what should I do?
Your code presumably can't parse 4 bytes (32 bit) to a signed integer, since this only contains 31 bits as one bit is reserved for the sign.
A solution would be to parse it into an unsigned integer (as Some random IT boy stated) and then convert the (16bit-)UInt to a (16bit-)Int:
fun main()
{
val u = "FFFFFFFF".toUInt(16) //16 as it is base 16
println(u) //prints "4294967295"
val v = u.toInt()
println(v) //prints "-1"
}
Use with caution as this will not work when your data is not of length 32: You can not parse FFFF and expect it to be -1 as it would be parsed to 0000FFFF which is equal to 65535.
For data lengths of 1, 2 or 8 bytes, look into the data types Byte, Short or Long and their respective Functions:
val u = "FFFFFFFF".toULong(16)
println(u) //prints 4294967295
val v = u.toLong()
println(v) //still prints 4294967295
It's -1 because the first bit of the 4 byte memory block decides the sign of the number. In this case since it's all 1's then it's a negative number. Then the value of this memory block is the Two's complement because we're dealing with a signed integer
The problem you're facing is not Kotlin specific: checkout this question from StackOverflow
Java has also trouble parsing such string to an Integer, but a Long has no trouble; because it has 4 more bytes to spare, and in fact, if you'd write the value literal 0xFFFFFFFF Kotlin grabs it as if it's a Long:
A quick fix for these could be to use the unsigned counterpart of the int UInt
"FFFFFFFF".toUInt(16) // 4294967295
Or just use a Long
In https://kotlinlang.org/

How to represent ObjC enum AVAudioSessionPortOverride which has declaration of int and string using Dart ffi?

I'm working on a cross platform sound API for Flutter.
We're trying to stop using Objective C/Swift for the iOS portion of the API and we're using Dart ffi as a replacement.
ffi(foreign function interface) allows dart to call into an Obj C API.
This means we need to create a dart library which wraps the Obj C audio library.
Whilst doing this we encountered the AVAudioSessionPortOverride enum which has two declarations; AVAudioSessionPortOverrideSpeaker = 'spkr' and AVAudioSessionPortOverrideNone = 0.
I'm confused as to what's going on here as one of these declarations is an int whilst the other is a string.
I note that AVAudioSessionPortOverride extends an NSUInteger so how is the string being handled. Is it somehow being converted to an int? if so any ideas on how I would do this in dart?
Here's what we have so far:
class AVAudioSessionPortOverride extends NSUInteger {
const AVAudioSessionPortOverride(int value) : super(value);
static AVAudioSessionPortOverride None = AVAudioSessionPortOverride(0);
static const AVAudioSessionPortOverride Speaker =
AVAudioSessionPortOverride('spkr');
}
'spkr' is in fact an int. See e.g. How to convert multi-character constant to integer in C? for an explanation of how this obscure feature in C works.
That said, if you look at the Swift representation of the PortOverride enum, you'll see this:
/// For use with overrideOutputAudioPort:error:
public enum PortOverride : UInt {
/// No override. Return audio routing to the default state for the current audio category.
case none = 0
/// Route audio output to speaker. Use this override with AVAudioSessionCategoryPlayAndRecord,
/// which by default routes the output to the receiver.
case speaker = 1936747378
}
Also, see https://developer.apple.com/documentation/avfoundation/avaudiosession/portoverride/speaker
Accordingly, 0 and 1936747378 are the values you should use.
Look at this
NSLog(#"spkr = %x s = %x p = %x k = %x r = %x", 'spkr', 's', 'p', 'k', 'r' );
Apple is doing everything your lecturer warned you against. You can get away with this since the string is 4 chars (bytes) long. If you make it longer you'll get a warning. The string gets converted to an int as illustrated in the code snippet above. You could reverse it by accessing the four bytes one by one and printing them as a character.
Spoiler - it will print
spkr = 73706b72 s = 73 p = 70 k = 6b r = 72

How to write selectively to an RFID tag? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
How can I efficiently write to an RFID tag without using a For loop. Right now I am looping and filling up all the blocks in the series. I want to make a program were I could fill in specific blocks with specific values. I want to know if there are other ways writing on RFID. The code below shows writing on RFID using the for loop which skips the integers.
Here's my code:
Private Sub RFIDAuth()
Dim SkipBlock As String
SkipBlock = ",3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,"
For i = 1 To 62
If SkipBlock.Contains("," & CStr(i) & ",") = False Then
Call ClearBuffers()
SendBuff(0) = &HFF 'CLA
SendBuff(2) = &H0 'P1: same for all source types
SendBuff(1) = &H86 'INS: for stored key input
SendBuff(3) = &H0 'P2: for stored key input
SendBuff(4) = &H5 'P3: for stored key input
SendBuff(5) = &H1 'Byte 1: version number
SendBuff(6) = &H0 'Byte 2
SendBuff(7) = CInt(i) 'Byte 3: sectore no. for stored key input
SendBuff(8) = &H60 'Byte 4 : Key A for stored key input
'SendBuff(8) = &H61 'Byte 4 : Key B for stored key input
SendBuff(9) = &H20 'Byte 5 : Session key for volatile memory
'SendBuff(9) = CDec(<INPUT>) 'Byte 5 : Session key for non-volatile memory
SendLen = &HA
RecvLen = &H2
retCode = SendAPDUandDisplay(0)
Base64StrfrmRFID = Base64StrfrmRFID & RFIDRead(i)
End If
Next
End Sub
SkipBlock: HashSet instead of string
The SkipBlock string and Contains(…) appear strange to me, use a HashSet<int> unless there is a good reason to use the string:
HashSet<int> SkipBlock = new HashSet<int>(){ 3, 7, 11, … };
and later:
if (SkipBlock.Contains(i)) {
Structure for the RFID layout
Use a struct to specify the layout of the RFID:
[StructLayout (LayoutKind.Explicit, Pack=1, Size=…)]
struct RFID_Block {
[FieldOffset(0)] public const byte CLA = 0xFF;
[FieldOffset(1)] public const byte INS = 0x86;
[FieldOffset(2)] public const byte P1 = 0x0;
…
[FieldOffset(7)] public int SectorNumber; // Should this be an int or a byte?
};
RFID_Block block1 = new RFID_Block();
block1.SectorNumber = i;
…
Use const for fields that are the same for each block and non-const fields for fields that may vary.
If a field has different meanings in different kinds of RFID blocks, you can define fields with the same FieldOffset, i.e.:
struct DualUseRFID_Block {
…
// Stored key input block
[FieldOffset(2)] public byte P2;
[FieldOffset(3)] public byte P3;
// Some other kind of RFID Block:
[FieldOffset(2)] public word FooBar;
Note:
first, FooBar has the same field offset as P2;
second, FooBar is of a different type than P2; and
third, FooBar occupies the same memory space as P2 and P3 either FooBar or P2 and P3 contain valid data.
Check the sizes of the fields do not confuse byte and int (4 bytes); i.e. withing an int and then something with an offset of one byte more is asking for problems (e.g. SendBuff(7) = CInt(i): Sendbuf(8) = &H60).
Check whether C# and the RFID chip agree about "endianess".
References
See MSDN about the StructLayout-attribute
See MSDN about using structs
See MSDN Structs tutorial; it includes details about memory layout and that fields in a struct can overlap if you like.

What's the format of boost.serialization's output

I tried to serialize a vector and a map container and output their value by cout. However, it is hard for me to get the meaning of boost's output. My code looks like this:
#include <iostream>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <boost/assign.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <sstream>
#include <fstream>
using namespace std;
int main()
{
vector<int> v = boost::assign::list_of(1)(3)(5);
map<int, string> m = boost::assign::map_list_of(1,"one")(2,"two");
std::stringstream ss;
boost::archive::text_oarchive oa(ss);
oa<<v<<m;
vector<int> v_;
map<int,string> m_;
boost::archive::text_iarchive ia(ss);
ia>>v_>>m_;
boost::archive::text_oarchive ib(cout);
ib<<v_<<m_;
return 0;
}
The output looks like this:
22 serialization::archive 9 3 0 1 3 5 0 0 2 0 0 0 1 3 one 2 3 two
What's the meaning of the numbers 9 3 0 before the value 1 3 5 I compose? How about the 0 0 2 0 0 0 ? Does the '3' between '1' and 'one' mean there are 3 characters ?
I'm not sure about some zeros in the map (maybe some version number or tracking levels) but for the rest :
22 (length of the signature)
serialization::archive (signature)
9 (archive version, 10 on boost 1.53)
3 (vector size)
0 (item version)
1 3 5 (vector items)
0 (map class tracking level ?)
0 (map class version ?)
2 (map size)
0 (item class tracking _level ?)
0 (item class version ?)
0 (item version)
1 (key) 3 (value length) one (value)
2 (key) 3 (value length) two (value)
Note that the content and format of the text output is Boost's internal business and may change with future Boost revisions, so your application shouldn't rely on the internal archive contents.
If you put these lines at the end of your code, you will obtain a human readable XML version of the archive.
boost::archive::xml_oarchive ib(cout);
ib<< boost::serialization::make_nvp("v", v_) << boost::serialization::make_nvp("m", m_); // ib<<v_<<m_;
return 0;
you will get this output, which describes it self:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<v>
<count>3</count>
<item_version>0</item_version>
<item>1</item>
<item>3</item>
<item>5</item>
</v>
<m class_id="1" tracking_level="0" version="0">
<count>2</count>
<item_version>0</item_version>
<item class_id="2" tracking_level="0" version="0">
<first>1</first>
<second>one</second>
</item>
<item>
<first>2</first>
<second>two</second>
</item>
</m>
</boost_serialization>
So #zacinter is correct and the three 0 after the 2 are: 1) item_version (of std::pair, the value type of the map) 2) tracking_level of std::pair and 3) version of std::pair.
22 is the length of the text "serialization::archive".
Every text that is archived has such a text-length-number in front of it I believe.
I'm aware that one should normally not try to parse the text_oarchive format of boost::serialization because the format is subject to change and should only ever be consumed by boost itself. In my case though, the software producing this output is a proprietary binary blob that uses messages on TCP and UDP encoded with boost::serialization. My (FOSS) client needs to be able to talk to it without having boost available. So I needed to figure out how all of this works and this SO question was the most useful I've found so far on this platform. So for any other poor souls in a similar situation, I wanted to share some more discoveries I made about the text_oarchive format.
I'll talk about an example as it would typically be produced by the proprietary application I need to inferface with. So here is some code with dummy classes A1, A2, A3, A4 and A5. A1 is the base class and all of the following classes are sub-classes inheriting from the one before.
#include "boost/serialization/export.hpp"
#include "boost/serialization/extended_type_info.hpp"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <iostream>
#include <sstream>
class A1 {
public:
A1(void) {}
virtual ~A1(void) {}
private:
unsigned int mem1 = 101;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_NVP(mem1);
}
};
BOOST_CLASS_EXPORT_KEY(A1);
class A2 : public A1 {
public:
A2(void) {}
private:
unsigned int mem2 = 102;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A1);
ar & BOOST_SERIALIZATION_NVP(mem2);
}
};
BOOST_CLASS_EXPORT_KEY(A2);
class A3 : public A2 {
public:
A3(void) {}
private:
virtual void foo() = 0;
unsigned int mem3 = 103;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A2);
ar & BOOST_SERIALIZATION_NVP(mem3);
}
};
BOOST_CLASS_EXPORT_KEY(A3);
class A4 : public A3 {
public:
A4(void) {}
private:
void foo() {}
unsigned int mem4 = 104;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A3);
ar & BOOST_SERIALIZATION_NVP(mem4);
}
};
BOOST_CLASS_EXPORT_KEY(A4);
class A5 : public A4 {
public:
A5(void) {}
private:
unsigned int mem5 = 105;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive & ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A4);
ar & BOOST_SERIALIZATION_NVP(mem5);
}
};
BOOST_CLASS_EXPORT_KEY(A5);
BOOST_CLASS_EXPORT_IMPLEMENT(A1);
BOOST_CLASS_EXPORT_IMPLEMENT(A2);
BOOST_CLASS_EXPORT_IMPLEMENT(A3);
BOOST_CLASS_EXPORT_IMPLEMENT(A4);
BOOST_CLASS_EXPORT_IMPLEMENT(A5);
BOOST_CLASS_VERSION(A1, 11)
BOOST_CLASS_VERSION(A2, 12)
BOOST_CLASS_VERSION(A3, 13)
BOOST_CLASS_VERSION(A4, 14)
BOOST_CLASS_VERSION(A5, 15)
void func(const A1 * const packet) {
std::string outpacket;
std::ostringstream stream;
boost::archive::xml_oarchive oa_xml(stream);
oa_xml << BOOST_SERIALIZATION_NVP(packet);
boost::archive::text_oarchive oa_text(stream);
oa_text << BOOST_SERIALIZATION_NVP(packet);
outpacket = stream.str();
std::cout << outpacket << std::endl;
}
int main() {
auto data = new A5();
func(data);
}
At the end, the main() function creates an A5 object and passes it to the function called func which is able to handle arguments of type A1 of which A5 is a sub-class. This is important as the boost::serialization output would be different if func took A5 as input directly.
Another important bit is the virtual destructor of A1. This one is required as well or otherwise one will not get the expected output for reasons that I do not yet understand.
To be able to better understand the text format, func encodes the data as XML as well as in the text format. To be able to use the XML output, BOOST_SERIALIZATION_BASE_OBJECT_NVP and BOOST_SERIALIZATION_NVP are applied wherever necessary. This does not seem to inferfere with the text output at all, which does not need these.
Each of the classes A1 to A5 has a member called mem1 to mem5, respectively. These are filled with the values 101 to 105, respectively, to better debug which integer in the text output stands for what.
To understand the output even better, BOOST_CLASS_VERSION is used to give all classes a unique class version. This helps because by default the class version is zero and then it's not clear what all the zeroes in the output stand for.
Without further ado, this is the output of compiling and running above code:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="18">
<packet class_id="1" class_name="A5" tracking_level="1" version="15" object_id="_0">
<A4 class_id="2" tracking_level="1" version="14" object_id="_1">
<A3 class_id="3" tracking_level="0" version="13">
<A2 class_id="4" tracking_level="1" version="12" object_id="_2">
<A1 class_id="0" tracking_level="1" version="11" object_id="_3">
<mem1>101</mem1>
</A1>
<mem2>102</mem2>
</A2>
<mem3>103</mem3>
</A3>
<mem4>104</mem4>
</A4>
<mem5>105</mem5>
</packet>
22 serialization::archive 18 1 2 A5 1 15
0 1 14
1 0 13 1 12
2 1 11
3 101 102 103 104 105
Some general observations:
in general, the values in the XML output seem to be in the same order as in the text output when reading the xml sequentially from top to bottom and left to right
consequently, the member variables of each of the sub-classes are bundled together all at the end of the output
class A3, which is the only class with a virtual function, is the only one with tracking level 0 (all the others are tracking level 1) and without an object id
I do not understand where the newlines in front of the object-ids come from in the text output but boost seems to be able to parse a message with newlines replaced by spaces just the same, so they do not seem to have any semantic meaning
Lets look at the values one-by-one by having each of them in their own line:
22 -- length of the string "serialization::archive"
serialization::archive -- BOOST_ARCHIVE_SIGNATURE defined in src/basic_archive.cpp
18 -- BOOST_ARCHIVE_VERSION as defined in src/basic_archive.cpp
1 -- class-id of A5
2 -- length of class name "A5"
A5 -- class name of A5
1 -- tracking level of A5
15 -- class version of A5
0 -- object-id of A5
1 -- tracking level of A4
14 -- class version of A4
1 -- object-id of A4
0 -- tracking level of A3 (the only "0" tracking level -- A3 is abstract class)
13 -- class version of A3 (notice the absence of object-id for abstract class A3 as well)
1 -- tracking level of A2
12 -- class version of A2
2 -- object-id of A2
1 -- tracking level of A1
11 -- class version of A1
3 -- object-id of A1
101 -- member of A1
102 -- member of A2
103 -- member of A3
104 -- member of A4
105 -- member of A5

How to define 64 bit constants in VB?

In Visual Basic
Friend Const xxx As UInt64 = 400 * 365 * 24 * 60 * 60 ''// Number of secs in 400 years
This fails with the error
constant expression not representable in type integer
The problem is 400 * 365 * 24 * 60 * 60 is larger than 2^32
I would have thought that by declaring the constant to be UInt64 that it would be OK to assign a 64 bit value to it
Aside from the fact that there are slightly more than 365 days each year (you need to add 97 leap days), each of the values that are multiplied to make up your constant are integer literals, and therefore until you assign them to the UInt64 it's all done in integer space. Try this:
Friend Const xxx As UInt64 = 400UL * 365UL * 24UL * 60UL * 60UL
Put a hash at the end of the constant, and declare it as a 'double'...
I did this with my bitmask fields:
Public Const EDIT_TRANSACTION As Double = 1073741824
Public Const EDIT_DWRDELIVERY As Double = 2147483648#
Public Const ENTER_DWRORDER As Double = 4294967296#
Public Const DELETE_DWRORDER As Double = 8589934592#
Public Const DELETE_TRANSACTION As Double = 17179869184#
Public Const DELETE_WATERORDER As Double = 34359738368#
Public Const ENTER_METERREADING As Double = 68719476736#
** EDIT **
I guess I got marked down on this because this was old code I wrote for VB6, and not exactly what you were asking for. So, if anyone reading this is using VB6, and have to pass Bitmask fields to something like SQL, this is what worked perfectly for me.
Otherwise, just keep voting my answer down. :)