I have a sample project here on github where I created a c++ wrapper class for an external C++ library that I want to use in Objective-C.
I don’t understand why my returned pointers are sometimes correct and sometimes wrong. Here’s sample output:
Test Data = 43343008
In Compress 43343008
Returned Value = 43343008
Casted Value = 43343008
Test Data = 2239023
In Compress 2239023
Returned Value = 2239023
Casted Value = 2239023
Test Data = 29459973
In Compress 29459973
Returned Value = 29459973
Casted Value = l.remote
Test Data = 64019670
In Compress 64019670
Returned Value =
Casted Value = stem.syslog.master
In the above output you can see that the 1st and 2nd click of the button outputs the results I was expecting. In each of the other clicks either the returned value or casted value are invalid. I’m assuming this is because my pointer is pointing to an address I wasn’t expecting. when running the app multiple times, any button click could be right or wrong.
I also tried with a single thread but experienced similar results.
The complete code is on github but here are the important bits.
ViewController.m
#import "ViewController.h"
extern const char * CompressCodeData(const char * strToCompress);
@implementation ViewController
...
// IBAction on the button
- (IBAction)testNow:(id)sender
{
[self performSelectorInBackground:@selector(analyze) withObject:nil];
}
- (void)analyze
{
@synchronized(self) {
const char *testData = [[NSString stringWithFormat:@"%d",
(int)(arc4random() % 100000000)] UTF8String];
NSLog(@"Test Data = %s", testData);
const char *compressed = CompressCodeData(testData);
NSLog(@"Returned Value = %s", compressed);
NSString *casted = [NSString stringWithCString:compressed
encoding:NSASCIIStringEncoding];
NSLog(@"Casted Value = %@\n\n", casted);
}
}
@end
SampleWrapper.cpp
#include <iostream>
#include <string.h>
#include <CoreFoundation/CoreFoundation.h>
using namespace std;
extern "C"
{
extern void NSLog(CFStringRef format, ...);
/**
* This function simply wraps a library function so that
* it can be used in objective-c.
*/
const char * CompressCodeData(const char * strToCompress)
{
const string s(strToCompress);
// Omitted call to static method in c++ library
// to simplify this test case.
//const char *result = SomeStaticLibraryFunction(s);
const char *result = s.c_str();
NSLog(CFSTR("In Compress %s"), result);
return result;
}
}
You are returning a pointer to at object that has been deallocated.
sdoes not exist afterCompressCodeData()function is over, so the pointer to it’s internal memory is invalid.You could allocate a chunk of memory to hold the response, but it would be up to the caller to release it.
Another solution is to pass in the memory to store the data into.