cast ptr ptr to Nim array - c

I've been stuck on a problem for some time now and I'm not getting anywhere. May one of you have mercy and help me.
I have transcribed some header files with c2nim. Debugging and many methods seem to work fine, but there is one section where I just can't get anywhere. The section I want to map looks like
C
typedef struct AVFormatContext {
...
AVStream **streams;
...
}
...
AVFormatContext *pFormatCtxInCam = NULL;
...
pFormatCtxInCam = avformat_alloc_context();
ret = avformat_open_input(&pFormatCtxInCam, "video=Venus USB2.0 Camera", inFrmt, &inOptions);
for (i = 0; i < pFormatCtxInCam->nb_streams; i++)
if (pFormatCtxInCam->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
video_stream_idx_cam = i;
Nim
type AVFormatContext* {.bycopy.} = object
...
streams*: ptr ptr AVStream
...
var pFormatCtxInCam: ptr AVCodecContext = nil
pFormatCtxInCam = avformat_alloc_context()
ret = avformat_open_input(pFormatCtxInCam.addr, "video=Venus USB2.0 Camera", inFrmt, inOptions.addr)
-> Problem
-> How can I access Streams as array ???
I can understand the basics in C and most of the memory layout, but here I reach my limits.
I try to cast in some ways.
Examples:
var streams = cast[array[0..0, ptr AVStream]](pFormatCtxInCam[].streams[].addr)
var streams = cast[array[0..0, AVStream]](pFormatCtxInCam[].streams[].addr)
var streams = cast[ref array[0..0, ptr AVStream]](pFormatCtxInCam[].streams)
var streams = cast[array[0..5, AVStream]](pFormatCtxInCam[].streams)
var streams = cast[ptr UncheckedArray[ptr AVStream]](pFormatCtxInCam[].streams)
var streams = cast[ptr UncheckedArray[ptr AVStream]](pFormatCtxInCam[].streams[])
var streams = cast[ptr UncheckedArray[ptr AVStream]](pFormatCtxInCam[].streams[][])
As you can see, I've tried a lot of things because I just don't know what to do...
-> How can I access ptr ptr in nim as an array?
Thx for help

var streams = cast[ptr UncheckedArray[ptr AVStream]](pFormatContext[].streams)
That seems to be the RIGHT answer. It is a pointer to an array of pointers to the elements.

Related

Solidity function with arrays gives overflow error

I have the same code without an array and it just works.
But In this one if i enter amount anything more than 0.001 ether it gives an overflow error.
I tried Other functions called in this one with errored values and they don't give an error.
CheckPairValue() and CheckSellPrice() works.
Code is to check my Wallet's worth in pancakeswap
Idk what's wrong.
Any help is appretiated.
Also Contract is verified on bscscan.
Contract
function GetSellValue(address[] memory TokenAddress, uint[] memory Amount)public view returns(uint256[] memory){
uint[] memory Value = new uint[](TokenAddress.length);
for(uint i = 0; i < TokenAddress.length; i++){
address Pair = CheckPairValue(TokenAddress[i], Amount[i] * 2);
address[] memory path;
if(Pair != PairAddresses[0]){
path = new address[](3);
path[0] = TokenAddress[i];
path[1] = Pair;
path[2] = PairAddresses[0];
}
else
{
path = new address[](2);
path[0] = TokenAddress[i];
path[1] = PairAddresses[0];
}
Value[i] = CheckSellPrice(Amount[i],path);
}
return Value;
}
0.001 ether input works , anything higher doesn't
I still don't know why remix errored like this.
But i've written a js code to call the contract and it works.

Rust: How to read a file block by block

i am totally new to rust. I want to read a file block by block/Chunks (every block should contain 16 Bytes) and write it - for this test scenario - into another file, f2. So i i tried it first with this code here:
let mut buf = [0;16];
let mut count = 0;
for byte in f1.bytes() {
if count == 16 {
do_smth(&mut f2, &mut buf);
count = 0;
let data = byte?;
buf[count] = data;
} else {
let data = byte?;
buf[count] = data;
count +=1;
}
}
The test bytes in the file f1 were:
0123456789abcdef-hello world, hello world!
The result in file f2 was
0123456789abcdefhello world, hel
Is there a performant way to increment the file cursor each iteration.
I read about the seek function and experimented a little with it but didn't come to a solution. Maybe this could be solved with an increment of the file cursor each interation?
This is the working solution.
let mut buffer = [0; 16];
let mut count = 0;
while let Ok(n) = f1.read(&mut buffer[..]) {
if n != 16 {
let rest = &buffer[0..n];
do_smth(&mut f2, &rest);
break;
} else {
do_smth(&mut f2, &mut buffer);
count += n;
}
}
There are two thing you could consider in order to improve performance:
Wrapping File in a BufReader to reduce the number of system calls and essentially chunking your file access.
You might want to check out the memmap crate, to use a memory mapped file.

C code to swift conversion

I am trying to convert below code to Swift:
{
// Set up the variables
double totalUsedMemory = 0.00;
mach_port_t host_port;
mach_msg_type_number_t host_size;
vm_size_t pagesize;
// Get the variable values
host_port = mach_host_self();
host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
vm_statistics_data_t vm_stat;
// Check for any system errors
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
// Error, failed to get Virtual memory info
return -1;
}
// Memory statistics in bytes
natural_t usedMemory = (natural_t)((vm_stat.active_count +
vm_stat.inactive_count +
vm_stat.wire_count) * pagesize);
natural_t allMemory = [self totalMemory];
return usedMemory;
}
My Swift code is:
{
// Set up the variables
var totalUsedMemory: Double = 0.00
var host_port: mach_port_t
var host_size: mach_msg_type_number_t
var pagesize:vm_size_t
// Get the variable values
host_port = mach_host_self()
host_size = mach_msg_type_number_t(MemoryLayout<vm_statistics_data_t>.stride / MemoryLayout<integer_t>.stride)
// host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
host_page_size(host_port, &pagesize);
var vm_stat: vm_statistics_data_t ;
// Check for any system errors
if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
// Error, failed to get Virtual memory info
return -1;
}
// Memory statistics in bytes
var usedMemory: Int64 = (Int64)((vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize);
return usedMemory;
}
I am getting these 2 errors:
**Binary operator '&' cannot be applied to operands of type '(host_info_t).Type' (aka 'UnsafeMutablePointer.Type') and 'vm_statistics_data_t' (aka 'vm_statistics')
in this statement
host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size)
And
Binary operator '*' cannot be applied to operands of type 'UInt32' and 'vm_size_t' (aka 'UInt')**
in this statement -
var usedMemory: Int64 = (Int64)((vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize);
Swift is a lot more strict about pointer types than C is, which can make it a real pain to interact with functions like this that expect you to pass pointers to types other than the actual type of the thing you're trying to pass to the function. So I agree with the commenters that you're probably better off leaving this function in (Objective-)C. However, if you absolutely have to convert to Swift, you're probably going to have to do something like this:
// Initialize a blank vm_statistics_data_t
var vm_stat = vm_statistics_data_t()
// Get a raw pointer to vm_stat
let err: kern_return_t = withUnsafeMutableBytes(of: &vm_stat) {
// Bind the raw buffer to Int32, since that's what host_statistics
// seems to want a pointer to.
let boundBuffer = $0.bindMemory(to: Int32.self)
// Call host_statistics, and return its status out of the closure.
return host_statistics(host_port, HOST_VM_INFO, boundBuffer.baseAddress, &host_size)
}
// Now take a look at what we got and compare it against KERN_SUCCESS
if err != KERN_SUCCESS {
// Error, failed to get Virtual memory info
return -1;
}

BCB6: How to put elements of a form in an array?

I'm building a simple game in C++Builder6 and I have 42 Image objects on a Form... At start-up I want all Image objects to be disabled, so I wonder can I put all of them in an array and simply loop thorough the entire array and make them Disabled? I know there must be a way, but I'm just new to programming :)
You have several options.
First: You can declare
Image* array[40];
And dynamically construct the image.
for ( int i = 0 ; i < 40; ++i ) {
image[i] = new Image(this); // where "this" is pointer to your form
image[i]->Parent = this;
// option below are optional
image[i]->Height = 50;
image[i]->Width = 50;
image[i]->Left = 40;
image[i]->Top = 100;
image[i]->Tag = i;
image[i]->OnClick = ButtonClick; // connect with method
}
Second option is declare
Image* array[40];
and manually set all values;
array[0] = Image1;
...
array[39] = Image40;
Then you will have all image in array and you can use loop for doing something on all Image

How can I store SpaceManager cpShape's in something like an array?

I'm trying to create a squishy ball with Cocos2d and Chipmunk (via SpaceManager) using a bunch of rects all chained together then joined with springs to a central body.
Something like these examples
But in order to do this, i think I need to store all the cpShapes in an array after I've created them so I can then loop through the array to link them all together with constraints.
However, when i try to put cpShapes in an array, I get an error telling me it's an "incompatible pointer type". So... I either need to use something other than an array (I've tried a set, that didn't work either) or I need to do something to the shape to make it compatible... but what? OR I need another aproach.
Any ideas?
Here's the code so far should it be relevant...
- (id) init
{
if ( (self = [super init]) ) {
SpaceManager * spaceMgr = [[SpaceManager alloc] init];
[spaceMgr addWindowContainmentWithFriction:1.0 elasticity:1.0 inset:cpv(5, 5)];
// This is a layer that draws all the chipmunk shapes
ChipmunkDrawingLayer *debug = [[ChipmunkDrawingLayer node] initWithSpace:spaceMgr.space];
[self addChild:debug];
int ballPeices = 10; // the number of peices I want my ball to be composed of
int ballRadius = 100;
float circum = M_PI * (ballRadius * 2);
float peiceSize = circum / ballPeices;
float angleIncrement = 360 / ballPeices;
CGPoint origin = ccp(240, 160);
float currentAngleIncrement = 0;
NSMutableArray *peiceArray = [NSMutableArray arrayWithCapacity:ballPeices];
for (int i = 0; i < ballPeices; i++) {
float angleIncrementInRadians = CC_DEGREES_TO_RADIANS(currentAngleIncrement);
float xp = origin.x + ballRadius * cos(angleIncrementInRadians);
float yp = origin.y + ballRadius * sin(angleIncrementInRadians);
// This is wrong, I need to figure out what's going on here.
float peiceRotation = atan2( origin.y - yp, origin.x - xp);
cpShape *currentPeice = [spaceMgr addRectAt:ccp(xp, yp) mass:1 width:peiceSize height:10 rotation:peiceRotation];
currentAngleIncrement += angleIncrement;
[peiceArray addObject:currentPeice]; //!! incompatible pointer type
}
spaceMgr.constantDt = 0.9/55.0;
spaceMgr.gravity = ccp(0,-980);
spaceMgr.damping = 1.0;
}
return self;
}
The incompatible pointer type is easy to explain :)
[NSMutableArray addObject] is defined as such:
- (void)addObject:(id)anObject
So what is an id then? Great question! Remember, Objective-C is still C at it's core. According to the Objective-C Programming Guide
typedef struct objc_object {
Class isa;
} *id;
That's great, now we know about *id but what about id itself? That's what is referenced in the method signature. For that, we have to look at objc.h
typedef id (*IMP)(id, SEL, ...);
Clearly, cpSpace* doesn't fit that, so you'll be getting incompatible pointer type if you try to put those into NSMutableArray using that message.

Resources