Convert a System::String into an int - c++-cli

I am trying to read the value from a sensor an plot some figures depending on that value. I want to compare the value from the sensor to an int variable and I think this is my problem. This is what I am doing:
System::String ^leido=this->serialPort1->ReadLine();
Int32 tb1Int;
Int32 cien=0;
bool ret = Int32::TryParse(leido, tb1Int);
//Drawing
if (tb1Int > cien){
PictureBox ^g = gcnew PictureBox;
g->Parent = this;
g->Location = Point(630,20);
g->Size::set(Drawing::Size(900,90));
g->BackColor::set(Color::Aquamarine);}
I am quite sure the problem is the comparision (tb1Int > cien). It should be fulfilled, but the code for drawing is not executed.
Any help??

Related

Byte[r,c,c] to Halcon HObject/HImage to byte[]

I am using Zivid.NET, Halcon.NET and ML.NET together. Zivid provides me with a 3D byte array (row, column, channel), Halcon uses HImages/HObjects, ML.NET functionality expects a 1D byte array (same as File.ReadAllBytes())
So far I used a workaround where:
I save()'d Zivid's imageRGBA as a PNG,
which I read with Halcon's read_image() that gives me a HObject.
After some graphical work I saved the HObject again as a PNG using write_image().
Using File.ReadAllBytes() to read that PNG I get the byte[] that my ML.NET functionalities expect.
But this is far from ideal with larger amounts of data.
What I need is:
a way to convert byte[r,c,c] images to HObject/HImage.
a way to convert HObject/HImage images to byte[].
Halcon's read_image() and write_image() don't seem to have any options for this and I haven't found anything helpful so far.
To create an HImage object from byte, you need a pointer to an array and then it's simple:
public HImage(string type, int width, int height, IntPtr pixelPointer)
To get a pointer and acess the data from HImage, the following function is needed:
IntPtr HImage.GetImagePointer1(out string type, out int width, out int height)
To convert from Zivid.NET's byte[r,c,c] to HImage one can:
var byteArr = imgRGBA.ToByteArray();
byte[,] redByteArray = new byte[1200, 1920];
byte[,] greenByteArray = new byte[1200, 1920];
byte[,] blueByteArray = new byte[1200, 1920];
for (int row = 0; row < 1200; row++)
for (int col = 0; col < 1920; col++)
{
redByteArray[row, col] = byteArr[row, col, 0];
greenByteArray[row, col] = byteArr[row, col, 1];
blueByteArray[row, col] = byteArr[row, col, 2];
}
GCHandle pinnedArray_red = GCHandle.Alloc(redByteArray, GCHandleType.Pinned);
IntPtr pointer_red = pinnedArray_red.AddrOfPinnedObject();
GCHandle pinnedArray_green = GCHandle.Alloc(greenByteArray, GCHandleType.Pinned);
IntPtr pointer_green = pinnedArray_green.AddrOfPinnedObject();
GCHandle pinnedArray_blue = GCHandle.Alloc(blueByteArray, GCHandleType.Pinned);
IntPtr pointer_blue = pinnedArray_blue.AddrOfPinnedObject();
GenImage3(out HObject imgHImage, "byte", 1920, 1200, pointer_red, pointer_green, pointer_blue);
pinnedArray_red.Free();
pinnedArray_green.Free();
pinnedArray_blue.Free();
Still working on the second part..
A better / more efficient method is very welcome.

VM error: revert in solidity while adding a uint8 to an int literal

I have this code:
function somePureFunction() public pure returns(uint256){
uint8 temp = 255;
return 2 + temp;
}
This code gives:
call to SimpleStorage.somePureFunction errored: VM error: revert.
revert
The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance.
But this works:
function somePureFunction() public pure returns(uint256){
return 2 + 255;
}
In particular your problem refers to value about temp that you give to this variable.
When you declare a variable with datatype uint8 you must to put inside it a value from 0 - 255 (255 excluded). For calculate the range of a specific uint, you can use this statement:
MaximumRange = 2*[numberOfBit]-1
Example:
Issue: I want know what is the range about uint32.
Expression = 2*32-1
Result = 0 - 4294967295
In your specific case, if you change this line:
uint8 temp = 255;
with this:
uint16 temp = 255;
it'll work successfully.
NOTE: You can change current datatype temp variable with other uint datatype like: uint16, uint32, uint64 and others. You must to keep in your mind the range of a single datatype and the value that you want to store inside the variable.

How can I read individual pixels from a CVPixelBuffer

AVDepthData gives me a CVPixelBuffer of depth data. But I can't find a way to easily access the depth information in this CVPixelBuffer. Is there a simple recipe in Objective-C to do so?
You have to use the CVPixelBuffer APIs to get the right format to access the data via unsafe pointer manipulations. Here is the basic way:
CVPixelBufferRef pixelBuffer = _lastDepthData.depthDataMap;
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
size_t cols = CVPixelBufferGetWidth(pixelBuffer);
size_t rows = CVPixelBufferGetHeight(pixelBuffer);
Float32 *baseAddress = CVPixelBufferGetBaseAddress( pixelBuffer );
// This next step is not necessary, but I include it here for illustration,
// you can get the type of pixel format, and it is associated with a kCVPixelFormatType
// this can tell you what type of data it is e.g. in this case Float32
OSType type = CVPixelBufferGetPixelFormatType( pixelBuffer);
if (type != kCVPixelFormatType_DepthFloat32) {
NSLog(#"Wrong type");
}
// Arbitrary values of x and y to sample
int x = 20; // must be lower that cols
int y = 30; // must be lower than rows
// Get the pixel. You could iterate here of course to get multiple pixels!
int baseAddressIndex = y * (int)cols + x;
const Float32 pixel = baseAddress[baseAddressIndex];
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
Note that the first thing you need to determine is what type of data is in the CVPixelBuffer - if you don't know this then you can use CVPixelBufferGetPixelFormatType() to find out. In this case I am getting depth data at Float32, if you were using another type e.g. Float16, then you would need to replace all occurrences of Float32 with that type.
Note that it's important to lock and unlock the base address using CVPixelBufferLockBaseAddress and CVPixelBufferUnlockBaseAddress.

StructureToPtr not copying primitive type fields in native struct to ref struct correctly

I have a native struct, (which is quite large so I have to use new key word to instantiate, below is just to make a MCVE I cant change the struct as it is provided as external dependencies),
struct NativeStruct
{
char BrokerID[11];
char InvestorID[13];
char InstrumentID[31];
char OrderRef[13];
char UserID[16];
char OrderPriceType;
char Direction;
double LimitPrice;
}
I want to convert NativeStruct to managed object, so I defined a ref struct to mirror it, this also used two enums as below,
public enum struct EnumOrderPriceTypeType
{
AnyPrice = (Byte)'1',
LimitPrice = (Byte)'2',
BestPrice = (Byte)'3',
LastPrice = (Byte)'4',
LastPricePlusOneTicks = (Byte)'5',
LastPricePlusTwoTicks = (Byte)'6',
LastPricePlusThreeTicks = (Byte)'7',
AskPrice1 = (Byte)'8',
AskPrice1PlusOneTicks = (Byte)'9',
AskPrice1PlusTwoTicks = (Byte)'A',
AskPrice1PlusThreeTicks = (Byte)'B',
BidPrice1 = (Byte)'C',
BidPrice1PlusOneTicks = (Byte)'D',
BidPrice1PlusTwoTicks = (Byte)'E',
BidPrice1PlusThreeTicks = (Byte)'F'
};
public enum struct EnumDirectionType
{
Buy = (Byte)'0',
Sell = (Byte)'1'
};
[StructLayout(LayoutKind::Sequential)]
public ref struct ManagedStruct
{
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 11)]
String^ BrokerID;
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 13)]
String^ InvestorID;
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 31)]
String^ InstrumentID;
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 13)]
String^ OrderRef;
[MarshalAs(UnmanagedType::ByValTStr, SizeConst = 16)]
String^ UserID;
EnumOrderPriceTypeType OrderPriceType;
EnumDirectionType Direction;
double LimitPrice;
};
Then I use StructureToPtr to copy the native object to managed object, and use WriteLine to test if the copy is successful,
NativeStruct *native = new NativeStruct();
ManagedStruct^ managed = gcnew ManagedStruct();
managed->LimitPrice = 95.5;
managed->BrokerID = "666666";
Marshal::StructureToPtr(managed, IntPtr(native), false);
int i;
for (i = 0; i < 11; i++)
Console::Write(native->BrokerID[i]);
Console::WriteLine();
Console::WriteLine(native->LimitPrice);
Console::WriteLine(L"Hello ");
Console::ReadLine();
My question is why LimitPrice is not copied successfuly? I have been battling this for a week, any help will be welcomed. Thanks a lot.
Marshal::StructureToPtr() can only work correctly when the managed and the native struct are an exact match. By far the simplest way to verify this is to check the sizes of the structures, they must be identical. So add this code to your program:
auto nlen = sizeof(NativeStruct);
auto mlen = Marshal::SizeOf(ManagedStruct::typeid);
System::Diagnostics::Debug::Assert(nlen == mlen);
Kaboom. The native struct takes 96 bytes and the managed one takes 104. Consequences are dire, you corrupt memory and that has a lot more unpleasant side effects than the LimitPrice member value getting copied to the wrong offset.
Two basic ways to trouble-shoot this. You can simply populate all of the managed struct members with unique values and check the first member of the native struct that has the wrong value. The member before it is wrong. Keep going until the you no longer get the kaboom. Or you can write code that uses offsetof() on the native struct members and compare them with Marshal::OffsetOf().
Just to save you the trouble, the problem are the enum declarations. Their size in the native struct is 1 byte but the managed versions take 4 bytes. Fix:
public enum struct EnumOrderPriceTypeType : Byte
and
public enum struct EnumDirectionType : Byte
Note the added : Byte to force the enum to take 1 byte of storage. It should be noted that copying the members one-by-one instead of using Marshal::StructureToPtr() is quicker and would have saved you a week of trouble.

How do I copy writeablebitmap to clipboard from an elevated trust silverlight application using P/Invoke?

I've got a silverlight 5 application that is running elevated trust in-browser. This allows us to do things that wouldn't ordinarily be possible in silverlight like having more access to the clipboard via P/Invoke.
What I need to be able to do is copy controls to the clipboard so they could be pasted into Word or Outlook. I can convert the controls to an image via WriteableBitmap but copying the data to the clipboard is something I'm having issues with.
Calling code:
WriteableBitmap bmp = new WriteableBitmap(elements[0], new ScaleTransform() { ScaleX = 1.0, ScaleY = 1.0 });
int[] p = bmp.Pixels;
int len = p.Length * 4;
byte[] result = new byte[len];
Buffer.BlockCopy(p, 0, result, 0, len);
CopyToClipboardViaPInvoke(result, ClipboardFormat.CF_BITMAP);
Copy function:
private void CopyToClipboardViaPInvoke(byte[] data, ClipboardFormat format)
{
IntPtr p = IntPtr.Zero;
if (Native.OpenClipboard(p))
{
GCHandle pinnedArray = GCHandle.Alloc(data, GCHandleType.Pinned);
IntPtr pointer = pinnedArray.AddrOfPinnedObject();
try
{
Native.EmptyClipboard();
IntPtr result = Native.SetClipboardData(format, pointer);
}
finally
{
Native.CloseClipboard();
pinnedArray.Free();
}
}
}
The result says it's successful, but paste does nothing. IsClipboardFormatAvailable also states that the format is available on the clipboard. I've also tried various ClipboardFormat inputs and other methods of converting the control to an image without any luck.
Update 1
Thanks to suggestions from user629926 I've got what I think is a little closer but I'm still missing something.
Native.EmptyClipboard();
IntPtr bmp = IntPtr.Zero;
GCHandle pinnedArray = GCHandle.Alloc(bytes, GCHandleType.Pinned);
IntPtr bmpPointer = pinnedArray.AddrOfPinnedObject();
Native.StartupInput sin = new Native.StartupInput() { GdiplusVersion = 1 };
Native.StartupOutput sout = new Native.StartupOutput();
IntPtr gdip = IntPtr.Zero;
int startup = Native.GdiplusStartup(out gdip, ref sin, out sout);
int created = Native.GdipCreateBitmapFromScan0(width, height, width * 4, 0x0026200A, bmpPointer, out bmp);
IntPtr result = Native.SetClipboardData(format, bmp);
Native.DeleteObject(bmp);
Native.GdiplusShutdown(ref gdip);
Use GdipCreateBitmapFromScan0 to get HBitmap from you array and pass it to clipboard and the DeleteObject to free it.
[DllImport("gdiplus.dll")]
static extern int GdipCreateBitmapFromScan0(int width, int height, int stride, int format, IntPtr scan0, out IntPtr bitmap);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);