I have few experience developing C applications and I am having a specific cast problem.
I have a char variable hard coded that I need to pass as a parameter in a function.
char * data = "058dd54970d65c";
This is the function:
PJ_DECL(pj_status_t) pjsua_call_make_call(pjsua_acc_id acc_id,
const pj_str_t *dst_uri,
const pjsua_call_setting *opt,
void *user_data,
const pjsua_msg_data *msg_data,
pjsua_call_id *p_call_id);
In order to use it:
pjsua_call_make_call(acc_id, &uri, 0, NULL, data, NULL);
As you can see I need a cast in the parameter 5. I am getting this error:
note: expected const struct pjsua_msg_data * but argument is of type char *
I try to use sprintf and other solutions but do not work. I would be gratefull if somebody could help me.
For completion i write my comment as new answer.
Create a new object of the pjsua_msg_data struct and fill your data into the msg_body property. After that you can simply use this object with the pjsua_call_make_call call.
Try this:
pjsua_msg_data data_alice;
data_alice.msg_body = data;
pjsua_call_make_call(acc_id, &uri, 0, NULL, data_alice, NULL);
Related
The definition to start a BLE scan is:
bool start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue = false);
The second parameter seems to be the callback when a scan is complete, being somewhat new to this Im unsure how to define it.
fwiw Ive tried this:
void OnScanResults(BLEScanResults scanResults)
{ }
and used it like this:
scanResults = scan->start(60, OnScanResults, true);
but obvious to others, that didnt work.
Please help me decypher that signature
void (*scanCompleteCB)(BLEScanResults)
you need to add & to OnScanResults because:
void (*scanCompleteCB)(BLEScanResults)
is a pointer to a function which takes a BLEScanResults, returns nothing and is called scanCompleteCB
So your call should be:
scanResults = scan->start(60, &OnScanResults, true);
just as a pointer to a int points to the address of a int
int pointedTo;
int* ptr = &pointedTo;
I'm trying to get the signature of a block in a Protocol method.
Here's a sample protocol:
#protocol ProtocolSample <NSObject>
- (void) doSomething: (void (^) (NSString *))a_block;
#end
I am able to get the signature of doSomething using the following:
Protocol *protocol_sample = #protocol(ProtocolSample);
unsigned int outCount;
struct objc_method_description *method_description_list = protocol_copyMethodDescriptionList(protocol_sample, YES, YES, &outCount);
struct objc_method_description method_description = method_description_list[0];
NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:method_description.types];
The signature I get is: v#:#?
My goal is to get the signature of the a_block. I've tried many methods including the following:
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
void *block;
[invocation getArgument:&block atIndex:2];
But block is always NULL.
How is it possible to get the signature of a_block?
Finally found the answer: const char *_protocol_getMethodTypeEncoding(Protocol *, SEL, BOOL isRequiredMethod, BOOL isInstanceMethod);
The method will get you the full signature of any selector!
There is also
extern const char* _Block_signature(id block);
which you can use for any arbitrary block object.
I am using the jansson library for a C project.
I have some problem understanding how to use the decref. Shall it be used after each new json_t parameter or not? As I understand jansson will borrow references to make this simpler.
If I run this program and check the values of a_id and a_test they are the same. I expected error or null for a_test.
I tried the same idea but then I added decref for json_acc and json_param but it crashed before I could even read the 1:th value. I was assuming a crash but not until a_test.
This is part of a bigger project but I try to add an example to show the essentials.
API side:
json_t* parObj;
void loadFile(char* path)
{
json_error_t error;
parObj = json_load_file(path, 0, &error);
}
int getAccountId(char* id)
{
json_t* json_acc = json_object_get(parObj, "accounts");
json_t* json_param = json_object_get(json_acc, id);
return json_integer_value(json_param);
}
void cleanJson()
{
json_decref(parObj);
}
Caller side:
loadFile("/home/jacob/accountDump.json");
int a_id = getAccountId("10");
cleanJson();
int a_test = getAccountId("10");
I did misunderstood how it is supposed to work, I assumed that decref would also set the memory to zero.
The API will remove the references and make it a free memory but as long as no one writes there or memset it to zero and the pointer is not set to null I can still read the values from that pointer.
I am trying to parse the URL in C using microhttpd library.
daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_SSL, PORT, NULL, NULL, &answer_to_connection, NULL, MHD_OPTION_HTTPS_MEM_KEY, key_pem, MHD_OPTION_HTTPS_MEM_CERT, cert_pem, MHD_OPTION_END);
When I run the function MHD_start_daemon a call back function answer_to_connection is called.
static int answer_to_connection(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
{
printf("URL:%s\n", url);
}
One of the parameters of answer_to_connection is const char *url. The url variable contains the string after https://localhost:port example: for http://128.19.24.123:8888/cars/ferrari the url value will be /cars/ferrari
But in case of http://128.19.24.123:8888/cars?value=ferrari the url is printing only cars.
I want to print cars?value=ferrari. How can I do that?
There is a tutorial on microhttpd library at https://www.gnu.org/software/libmicrohttpd/tutorial.html
But I can't find any solution to this problem there.
CAVEAT EMPTOR: I have not used this library, this answer is based on a quick perusal of the API.
It looks like you can't access the whole original URL, because microhttpd parses it for you. Instead you access the individual query string values using MHD_lookup_connection_value, like this:
value = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "value");
That would return a pointer to the value of the query string argument, or null if not found.
You can also use MHD_get_connection_values to iterate over the query string components. In that case you would call it like this:
num = MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, iterator, cls);
iterator would be a callback function to receive the GET query arguments, one by one.
See also: the Handling requests section in the manual.
Can anybody help me to find out how to call rrd_update_r function of the rrdtool c API from http://oss.oetiker.ch/rrdtool/index.en.html?
It was quite easy to call the non-threadsafe version of rrd_update, but this one is more tricky...
normal rrd_update:
char *updateparams[] = {
"rrdupdate",
rrd_file,
values,
NULL
};
rrd_clear_error();
result = rrd_update(3, updateparams); //argc is first arg
Because the programm has to run in a multithreaded environment I got several errors by not using the threadsafe functions!
But it is not so easy to use rrd_update_r, because it requires a template too...
int rrd_update_r(const char *filename, const char *_template,
int argc, const char **argv);
and I really have no idea how to create one...
char *updateparams[] = {
"rrdupdate",
rrd_file,
values,
NULL
};
rrd_clear_error();
result = rrd_update_r(rrd_file, NULL,3, updateparams);
does not work and produces the following error when executing it...
error: /var/tmp/rrds/1.rrd: expected timestamp not found in data source from rrdupdate
Hopefully someone can help me!
thx and br,
roegi
Well, looking at the source code...
It appears that rrd_update_r does not want to see the "rrupdate" argument. So try just passing rrd_file and values as a 2-element argv.
Actually the source for rrd_update is not hard to read; you can find it in src/rrd_update.c. And rrd_update_r appears to be a much lower-level function that rrd_update itself calls. So this may not actually fix your underlying problem.
Now it is working!
Nemo - thx for your help!
It was not exactly your solution but it was a hint to the right direction!
It works with:
/*
rrd_file is a char * to "/var/tmp/1.rrd"
NULL says not to use a template
1 --> argc
values is a char * to "N:value-1:value-2:.....:value-n"
*/
result = rrd_update_r(rrd_file, NULL, 1, (void *) &values);