How to call C function from Objective-C - ios

I'm currently trying to convert videos on iOS using FFmpeg.
I've modified their example in transcoding.c according to my needs.
How do I actually call the following function from Objective-C:
int mainFunction(int argc, char **argv);
I'm not sure on how to provide the arguments from Objective-C.
Any help would greatly be appreciated.

Objective-C is a superset of C. All you need to do is call it from your Objective-C code.
char* args[] = { "foo", "bar", NULL }; // Might need the NULL to emulate command line arguments.
int result = mainFunction(2, args);
You could pass argc and argv directly from your own main
int main(int argc, char** argv)
{
int result = mainFunction(argc, argv);
}
If your arguments are in an array of NSStrings, you'll need to convert them to a normal C array of C strings:
char** cStringArray = malloc(([stringArray count] + 1) * sizeof(char*));
for (int i = 0 ; i < [stringArray count] ; ++i)
{
NSString* aString = [stringArray objectAtIndex: i];
cStringArray[i] = [aString UTF8String];
}
cStringArray[[stringArray count]] = NULL;
int result = mainFunction([stringArray count], cStringArray);
free(cStringArray);
It's a long time since I last did any Objective-C, so apologies for any syntax errors.

Related

iOS a Very Amazing(malloc_error_break)

first this my code
#pragma pack (4)
typedef struct _Login{
char user[32];
char pwd[32];
int userID;
}Login,*PLogin;
const unsigned long MSG_TAG_HEADER_YXHY = 0x59485859;
#pragma pack (2)
typedef struct tagTcpPacketHeader
{
int ulHtag;
char ucVersion;
char ucCmd;
int ulUserId;
short usPacketNum;
int ulDataLen;
}TcpPacketHeader,*LPTcpPacketHeader;
#pragma pack ()
const unsigned int TCP_HEADER_PACKET_LEN = sizeof(TcpPacketHeader);
- (NSData*)sendDataFileWithUserId:(const int)nUserId nCmd:(const int)nCmd pData:(NSData*)data{
NSData* sendData;
void* sendObj = malloc(data.length);
[data getBytes:sendObj length:data.length];
static int nPacketNum = 0;
int nLen = (int)data.length + TCP_HEADER_PACKET_LEN;
char *pTmpBuf = malloc(nLen);
LPTcpPacketHeader tcpHeader = (LPTcpPacketHeader)pTmpBuf;
tcpHeader->ulHtag = MSG_TAG_HEADER_YXHY;
tcpHeader->ucVersion = 1;
tcpHeader->ucCmd = nCmd;
tcpHeader->ulUserId = nUserId;
tcpHeader->usPacketNum = nPacketNum;
tcpHeader->ulDataLen = nLen;
memcpy(tcpHeader + TCP_HEADER_PACKET_LEN,sendObj, data.length);
sendData = [NSData dataWithBytes:pTmpBuf length:nLen];
nPacketNum++;
free(pTmpBuf);
free(sendObj);
return sendData;
}
- (NSData*)get_File_Login:(NSString*)userID{
int length = sizeof(Login);
Login log_in = {"123","456",userID.intValue};
NSData* login_data = [NSData dataWithBytes:&log_in length:length];
NSData* ret = [self sendDataFileWithUserId:log_in.userID nCmd:5 pData:login_data];
return ret;
}
Use
NSData* ms = [self get_File_Login:#"123"];
NSLog(#"%#",ms);
After frequent use can be a problem
question
This question makes me very headache why appear “ set a breakpoint in malloc_error_break to debug ”
I have added the "malloc_error_break" the breakpoint,But it doesn't work......
Who can tell me the answer???
When you use the pointer in memcpy this way
memcpy(tcpHeader + TCP_HEADER_PACKET_LEN,sendObj, data.length);
this means that you want to copy into memory location pointed by tcpHeader plus TCP_HEADER_PACKET_LEN times the size of the data the pointer points to. It is the same as doing &tcpHeader[TCP_HEADER_PACKET_LEN].
Assuming you want to write to a location right after the header there are two ways to fix it:
1) use a pointer with a size of 1, meaning a char*. In your code you have a pointer pTmpBuf that is such so just change the code to:
memcpy(pTmpBuf + TCP_HEADER_PACKET_LEN, sendObj, data.length);
2) use the size 1 for this calculation. Since the size of the data it points to is the same as TCP_HEADER_PACKET_LEN then multiplying it by one gives the correct location:
memcpy(tcpHeader + 1, sendObj, data.length);
I would recommend the first since it's clear what you are calculating. In the second it is unclear why you would add one, as well as using a pointer to one type when copying data that isn't that type.

Coding a PDF Text Parser in swift

I'm currently developing a pdf text parser completely in swift.
I was looking trough the PDFKittens code and found this in the stringwithpdfstring method (In SimpleFont.m) taking a CGPDFStringRef as parameter.
const unsigned char *bytes = CGPDFStringGetBytePtr(pdfString);
NSUInteger length = CGPDFStringGetLength(pdfString);
// Translate to Unicode
for (int i = 0; i < length; i++)
{
unichar cid = bytes[i];
unichar uni = [self.toUnicode unicodeCharacter:cid];
}
From my understanding *bytes is a CChar, what is this method exactly iterating trough? When I translate this code to swift I receive the error that
Type UnsafePointer? has no subscript members.
What is the equivalent of that objective c code in swift...?

ios blocks with different parameters

Iam completely new to ios Blocks and have no idea about the syntax .Iam trying to create a block which takes two parameter one an int and another a NSString and returns an int value. Iam getting error and don't know how to proceed help me with some tutorial or guide me through this is the block .
int (^indexFinder)(int , NSString *) = int (^(int passedValue , NSString * passedText) {};
Do like this:
int (^indexFinder)(int , NSString *) = ^(int a, NSString * b) {
return 10 ;
} ;
int i = indexFinder(1, #"") ;
NSLog(#"%d", i) ;
I learn it from Blocks programming topic
should be like this:
int (^indexFinder)(int , NSString *) = ^int (int passedValue , NSString * passedText) {
NSLog(#">> %d %#",passedValue,passedText);
return 0;
};
indexFinder(0,#"hello");
here are some links that tackles about block: link1, link2

I get a Suspicious pointer conversion in function main. How to get rid of this?

I'm new here at stackoverflow. The title is my question. Can someone please help me on this. Thanks. I've been working on this for like 3 days.
This part of code encodes the file to a huffman code
void encode(const char *s, char *out)
{
while (*s) {
strcpy(out, code[*s]);
out += strlen(code[*s++]);
}
}
This part of code deciphers the file from a huffman code to a human readable code
void decode(const char *s, node t)
{
node n = t;
while (*s) {
if (*s++ == '0') n = n->left;
else n = n->right;
if (n->c) putchar(n->c), n = t;
}
putchar('\n');
if (t != n) printf("garbage input\n");
}
This part is where I get my error.
int main(void)
{
int i;
const char *str = "this is an example for huffman encoding", buf[1024];
init(str);
for (i=0;i<128;i++)
if (code[i]) printf("'%c': %s\n", i, code[i]);
encode(str, buf); /* I get the error here */
printf("encoded: %s\n", buf);
printf("decoded: ");
decode(buf, q[1]);
return 0;
}
Declare 'buf' in a different line, and not as 'const':
char buf[1024];
The const applies to all the declarations on the line, so you're declaring buf as a const char[1024]. That means that calling encode casts away the constness, resulting in the warning.
Avoid having multiple variable declarations on the same line, unless they are all exactly the same type.

How to convert long long to 8 byte array in objective C

In my application i have to convert long long number into 8 byte array. Then i have to convert 8 byte array into hexadecimel string. Can you please help me in this. i'm struck up.
One way to do integer/byte array conversion is to use a union:
union {
long long l;
uint8_t b[sizeof(long long)];
} u;
u.l = mylonglong;
Then u.b[] contains the bytes, which can be accessed individually.
EDIT: Please note as pointed out by #NikolaiRuhe this use of union can lead to undefined behaviour, so it might be best to use memcpy() instead:
uint8_t b[sizeof(long long)];
memcpy(b, &mylonglong, sizeof(b));
If you want the hex string of the long long in native-endian order, then:
void hexChar(uint8_t b, char *out)
{
static const char *chars = "0123456789abcdef";
out[0] = chars[(b >> 4) & 0xf];
out[1] = chars[b & 0xf];
}
// Make sure outbuf is big enough
void hexChars(const uint8_t *buffer, size_t len, char *outbuf)
{
for (size_t i = 0; i < len; i++)
{
hexChar(buffer[i], outbuf);
outbuf += 2;
}
*outbuf = '\0';
}
and call it with:
char hex[32];
hexChars(u.b, sizeof(u.b), hex);
However if instead you want the hex value of the long long:
char hex[32];
sprintf(hex, "%llx", mylonglong);
would that do the trick ?
#include <stdio.h>
int main() {
long long int val = 0x424242;
char str_val[32];
snprintf(str_val, sizeof(str_val), "%#llx", val);
printf("Value : %s\n", str_val);
}

Resources