How can I pass void *payload object in git_index_add_all() method of libgit2 library? - libgit2

I am running libgit2 v0.23.0. I am calling method git_index_add_all which takes following parameters:
git_index * index
const git_strarray * pathspec
unsigned int flags
git_index_matched_path_cb callback
void * payload
I am not able to get how do I need to create last void *payload parameter
My code is :
git_index *idx = NULL;
git_index_matched_path_cb matched_cb = NULL;
int error = 0;
error = git_index_open(&idx, "repofolder/.git/index");
char *paths[] = {"repofolder/*"};
git_strarray arr = {paths, 1};
error = git_index_add_all(idx, &arr, GIT_INDEX_ADD_DEFAULT,matched_cb, ?);
could anybody suggest me, what should be way to create or get payload type object ?

The payload argument is the standard way of creating a closure in C. Your callback will receive whatever pointer you put in as its payload argument. It should be a pointer to whatever variable/structure you need for the callback to do its work.
If you don't need any data, then pass in NULL.

Related

'proc' undefined when trying to add a system call to xv6

I'm trying to add a "clone" system call to the xv6 os. The call creates a new kernel thread which shares the calling process’s address space. The following is my code in proc.c
int clone(void(*fcn)(void*), void* arg, void* stack)
{
int i, pid;
struct proc *np;
int *myarg;
int *myret;
if((np = allocproc()) == 0)
return -1;
np->pgdir = proc->pgdir; //Here's where it tell's me proc is undefined
np->sz = proc->sz;
np->parent = proc;
*np->tf = *proc->tf;
np->stack = stack;
np->tf->eax = 0;
np->tf->eip = (int)fcn;
myret = stack + 4096 - 2 * sizeof(int *);
*myret = 0xFFFFFFFF;
myarg = stack + 4096 - sizeof(int *);
*myarg = (int)arg;
np->tf->esp = (int)stack + PGSIZE - 2 * sizeof(int *);
np->tf->ebp = np->tf->esp;
np->isthread = 1;
for(i = 0; i < NOFILE; i++)
if(proc->ofile[i])
np->ofile[i] = filedup(proc->ofile[i]);
np->cwd = idup(proc->cwd);
safestrcpy(np->name, proc->name, sizeof(proc->name));
pid = np->pid;
acquire(&ptable.lock);
np->state = RUNNABLE;
release(&ptable.lock);
return pid;
}
Most of the implementations I found look just like this, however, whenever I try to make it tells me that 'proc' is undefined. Most implementations of clone that I've seen look nearly identical, with all of them utilizing proc. I'd be happy to share my sysproc.c code as well if that would help in any way.
Thank you!
This has nothing to do with your system call's implementation because proc global variable is being set by the scheduler right before resuming a selected "runnable" process.
The reason for null would probably be because calling this function from a wrong context.
A system call implementation is expected to be executed from a wrapping function named sys_mysysfunc that syscall function called due to a system call inerrupt initiated by a user application code.
Please share with us your entire implementation flow for additional assistance.

Using method_getReturnType to call specific types of instance member functions

I'm new to Objective-C so I don't have much idea about the language.
What I'm trying to do is go through all available instance methods of an object and call the ones that take no arguments, return bool and start with the string "func".
Here's how I get the methods:
uint32_t methodCount = 0;
Method * methods = class_copyMethodList(object_getClass(self), &methodCount);
I iterate through the methods and when the above condition matches, try to call them:
NSString * methodName = [NSString stringWithUTF8String:sel_getName(method_getName(method))];
char retTyp[10];
method_getReturnType(method, retTyp, 10);
const char * desiredRetType = "B";
if([methodName hasPrefix:#"func"] &&
(0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
(2 == method_getNumberOfArguments(method)))
{
bool * (* testMethod) (id, Method) = (void (*) (id, Method, ...)) method_invoke;
result = testMethod(self, method);
}
I had to experimentally figure out what the return type string is (turns out it's "B" for bool), and the number of arguments.
I'm getting the following error on the line where I'm trying to call the function using method_invoke:
cannot initialize a variable of type 'bool *(*)(__strong id, Method)' (aka 'bool *(*)(__strong id, objc_method *)') with an rvalue of type 'void (*)(__strong id, Method, ...)' (aka 'void (*)(__strong id, objc_method *, ...)'): different return type ('bool *' vs 'void')
Is there a better way to way to do this than class_copyMethodList?
How do I cast the function correctly so as to not get an error?
Is it possible that the method_getReturnType() conversion of return
types may change from system to system? Or is it always B for bool?
NVM, I figured it out. Instead of using method_invoke on the method name, I did this:
NSString * methodName = [NSString stringWithUTF8String:sel_getName(method_getName(method))];
char retTyp[10];
method_getReturnType(method, retTyp, 10);
const char * desiredRetType = "B";
if([methodName hasPrefix:#"func"] &&
(0 == strncmp(retTyp, desiredRetType, strlen(desiredRetType))) &&
(2 == method_getNumberOfArguments(method)))
{
SEL testMethod = method_getName(method);
return [self performSelector:testMethod];
}

Unable to understand the certain operator in Swift

I have been changing some SWIFT code into OBJECTIVE-C, and I am stuck at certain part of the code, where I am unable to understand if it is a condition or something else.
Following is the code and I am stuck on 9th line stating :
if let channel1Buffer = buffer.floatChannelData?[0]
What I do not understand here is the above if condition is checking if "buffer.floatChannelData" is null, and then proceeding to get the first index, or is it something else.
input.installTap(onBus: 0, bufferSize:4096, format:format, block: { [weak self] buffer, when in
guard let this = self else {
return
}
print("Buffer Float Channel Data: ", buffer.floatChannelData as Any);
**if let channel1Buffer = buffer.floatChannelData?[0]** {
print("channel1Buffer: ", channel1Buffer);
/// encode PCM to mp3
let frameLength = Int32(buffer.frameLength) / 2;
print("frameLength: ", frameLength);
let bytesWritten = lame_encode_buffer_interleaved_ieee_float(this.lame, channel1Buffer, frameLength, this.mp3buf, 4096);
// `bytesWritten` bytes stored in this.mp3buf now mp3-encoded
print("\(bytesWritten) encoded");
this.file.append(this.mp3buf, length: Int(bytesWritten));
// #TODO: send data, better to pass into separate queue for processing
}
})
Let's take it part by part - buffer.floatChannelData?[0]
buffer has property named floatChannelData which is optional so it has ? at the end. then it takes that optional which accepts subscription [0] which also returns optional value. So it continues inside {} only if floatChannelData is not nil AND it's first value is not nil
Your Objc should look like
float *const *channelData = [buffer floatChannelData];
if (channelData) {
float *channel1Buffer = channelData[0]; //this might crash if channelData is empty
...
The line tries to assign the variable channel1Buffer the value of buffer.floatChannelData[0], and the code within {} is only executed if that assignment is successful. It may for instance fail if buffer.floatChannelData is nil or buffer.floatChannelData[0] is nil.

Check the class of an object from Box2d's user data

I am trying to determine the type of object when detecting collision with Box2d. I want to be able to assign the user data to an object and check to see if its of the correct class type
id object = b->GerUserData():
Then
if([object isKindOfClass:[MyClassObject class]])
However i just get the error "Cannot initialize a variable of type'id' with an rvalue of type 'void*'
Can anyone help me out.
Thanks
Your problem is you are trying to assign an object of type 'id' to a void * type
The method call body->GetUserData(); returns a void pointer. Here it is as defined in the header file of b2Body.h
/// Get the user data pointer that was provided in the body definition.
void* GetUserData() const;
Now, if you are using ARC (Automatic Reference Counting), you need to perform an additional step to cast it back.
id object = (__bridge id) b->GetUserData();
If you are not using ARC, then...
id object = (id) b->GetUserData();
As for checking the type, there are many ways to do this. I personally prefer having an enum called GameObjectType. I can then assign the type in the appropriate constructor of the object. Here is an example of how I do it in my games
for (b2Body * b = world->GetBodyList(); b != NULL; b = b->GetNext()) {
Box2DSprite * sprite = (__bridge Box2DSprite*) b->GetUserData();
id obj = (__bridge id) b->GetUserData();
if (sprite.gameObjectType == kGroundTypeStatic
|| sprite.gameObjectType == kWallType
|| sprite.gameObjectType == kGroundTypeDynamic) {
// Insert Logic here
} // end if
sprite.position = ccp(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
sprite.rotation = CC_RADIANS_TO_DEGREES(b->GetAngle() * -1);
} // end for
Here is how I would go about creating the sprite (Using ARC)
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position = b2Vec2(location.x/PTM_RATIO,
location.y/PTM_RATIO);
// Setting the enum value
self.gameObjectType = kTankType;
self->body = self->world->CreateBody(&bodyDef);
self->body->SetUserData((__bridge void*) self); // Obtain sprite object later
GB2ShapeCache * shapeCache = [GB2ShapeCache sharedShapeCache];
[shapeCache addFixturesToBody:self->body forShapeName:#"Earth_Tank"];
self.anchorPoint = [shapeCache anchorPointForShape:#"Earth_Tank"];
Hope this helps
I'm guessing the error is on this line:
id object = b->GetUserData();
That might be because the return type is void pointer. Try to cast it like that:
id object = (id)b->GetUserData();

XOR reverse a string in objective-c get an error

I want to use the following code to reverse a char * type string in objective-c:
- (char *)reverseString:(char *)aString
{
unsigned long length = strlen(aString);
int end = length - 1;
int start = 0;
while (start < end) {
aString[start] ^= aString[end];
aString[end] ^= aString[start];
aString[start] ^= aString[end];
++start;
--end;
}
return aString;
}
But I got an error EXC_BAD_ACCESS at this line
aString[start] ^= aString[end]
I googled and found people said I can't modify a literal string because it is readonly. I am new to C so I wonder what simple data type (no object) I can use in this example? I get the same error when I use (char []) aString to replace (char *) aString.
I assume you're calling this like
[myObj reverseString:"foobar"];
The string "foobar" here is a constant literal string. Its type should be const char *, but because C is braindead, it's char *. But it's still constant, so any attempt to modify it is going to fail.
Declaring the method as taking char[] actually makes no difference whatsoever. When used as a parameter type, char[] is identical to char*.
You have two choices here. The first is to duplicate the string before passing it to the method. The second is to change the method to not modify its input string at all but instead to return a new string as output. Both can be accomplished using strdup(). Just remember that the string returned from strdup() will need to be free()'d later.