在C++和Objective-C

问题描述:

使用字符串指针我有一个示例项目here on github,我创建了一个C++包装类,我想在Objective-C使用一个外部的C++库。在C++和Objective-C

我不明白为什么我返回的指针有时是正确的,有时是错误的。这里是示例输出:

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 

在上面的输出中,您可以看到按钮的第一次和第二次点击输出我期待的结果。在其他每次点击中,返回值或铸造值都是无效的。我假设这是因为我的指针指向了一个我并不期待的地址。当多次运行该应用程序时,任何按钮点击都可能是正确的或错误的。

我也试过用单线程,但经历了类似的结果。

完整的代码是github但这里有重要的位。

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; 
    } 

} 

您在返回对象的指针已被释放。

const string s(strToCompress); 
… 
const char *result = s.c_str(); 

NSLog(CFSTR("In Compress %s"), result); 
return result; 

s不存在后CompressCodeData()功能是结束了,所以指针,它的内存是无效的。


你可以分配一块内存来保存响应,但是由调用者来释放它。

char *compressed = CompressCodeData(testData); 
NSLog(@"Returned Value = %s", compressed); 

NSString *casted = [NSString stringWithCString:compressed 
             encoding:NSASCIIStringEncoding]; 
free(compressed); 
NSLog(@"Casted Value = %@\n\n", casted); 

… 

const char * CompressCodeData(const char * strToCompress) 
… 
char *result = strdup(s.c_str()); 

另一种解决方案是传入内存来存储数据。

char compressed[2048]; // Or whatever! 
CompressCodeData(testData, compressed, sizeof(compressed)); 
NSLog(@"Returned Value = %s", compressed); 

NSString *casted = [NSString stringWithCString:compressed 
             encoding:NSASCIIStringEncoding]; 
NSLog(@"Casted Value = %@\n\n", casted); 

… 

void CompressCodeData(const char * strToCompress, char *result, size_t size) 
… 
s.copy(result, size - 1); 
result[s.length() < size ? s.length() : size-1] = '\0'; 
+0

谢谢你,这回答完美。 – JamesOR