- (IBAction)buttonPushed:(UIButton *)sender {
self.mmclass = [[CplusplusMMClass alloc]init]; // bad practice; but showing code
NSString *str = [self.mmclass fetchStringFromCplusplus];
[self populateLabel:str];
}
这里是CplusplusMMClass .h和 .mm文件。
#import <Foundation/Foundation.h>
#import "WrapperClass.h"
@interface CplusplusMMClass : NSObject
@end
@interface CplusplusMMClass()
@property (nonatomic, strong) WrapperClass *wrapper;
- (NSString*)fetchStringFromCplusplus;
@end
#import "CplusplusMMClass.h"
#import "WrapperClass.h"
@implementation CplusplusMMClass
- (NSString*)fetchStringFromCplusplus {
self.wrapper = [[WrapperClass alloc] init];
NSString * result = [self.wrapper getHelloString];
return result;
}
@end
这是WrapperClass .h和.mm文件。
#ifndef HEADERFILE_H
#define HEADERFILE_H
#import <Foundation/Foundation.h>
#if __cplusplus
#include "PureCplusplusClass.h"
@interface WrapperClass : NSObject
@end
@interface WrapperClass ()
- (NSString *)getHelloString;
@end
#endif
#endif
#import "WrapperClass.h"
#include "WrapperClass.h"
#include "PureCplusplusClass.h"
using namespace test;
@interface WrapperClass ()
@property (nonatomic) HelloTest helloTest;
@end
@implementation WrapperClass
- (NSString *)getHelloString {
self.helloTest = *(new HelloTest);
std::string str = self.helloTest.getHelloString();
NSString* result = [[NSString alloc] initWithUTF8String:str.c_str()];
return result;
}
@end
这里是PureCplusplusClass.h和.cpp文件。
#ifndef __HelloWorld__PureCplusplusClass__
#define __HelloWorld__PureCplusplusClass__
#include <stdio.h>
#include <string>
using namespace std;
namespace test {
class HelloTest
{
public:
std::string getHelloString();
};
}
#endif /* defined(__HelloWorld__PureCplusplusClass__) */
#include <stdio.h>
#include <string>
std::string test::HelloTest::getHelloString() {
std::string outString = "Hello World";
return outString;
}
这段代码并不完美!我遇到了命名空间测试无法被识别的问题。我会在有更新时进行更新。
另一个(人为制造的)例子:
将C++类用作实例变量:
文件Foo.h
#import <Foundation/Foundation.h>
@interface Foo : NSObject
@property (nonatomic, readonly) NSString* what;
@end
文件:Foo.mm
#import "Foo.h"
#include <string>
@implementation Foo {
std::string _string; // C++ class must have a default c-tor
}
- (id)init
{
self = [super init];
if (self) {
_string = "Hello, World!"
}
return self;
}
- (NSString*) what {
NSString* result = [[NSString alloc] initWithBytes:_string.data()
length:_string.size()
encoding:NSUTF8StringEncoding];
return result;
}
@end
可执行文件可能需要显式链接C++库,例如通过为“其他链接器标志”添加附加标志:-lc++
或者将main.m
文件重命名为main.mm
。
后一种方法在选择“正确”的库方面更为稳健,因为工具链会自动完成这一操作。但也许对于检查项目的其他人员来说,重命名“main.m”可能不太明显,并可能导致混淆。
Objective-C的IOS网银示例
- (IBAction)Button:(id)sender {
NSMutableArray *userdata=[[NSMutableArray alloc]initWithObjects:@"Name",@"CreditcardNumber",@"Pinnumber",@"Active", nil]; // arrkey = userdata.
NSMutableArray *Yogesh=[[NSMutableArray alloc]initWithObjects:@"Yogesh",@"908380637367",@"5656",@"yes", nil];
NSMutableArray *sabari=[[NSMutableArray alloc]initWithObjects:@"Sabari",@"7635298721",@"6543",@"no",nil];
NSMutableArray *rajesh=[[NSMutableArray alloc]initWithObjects:@"rajesh",@"8373197272",@"8765",@"yes",nil];
NSMutableArray *Ramya =[[NSMutableArray alloc]initWithObjects:@"Ramya ",@"123456",@"9898",@"No",nil];
NSMutableDictionary * dic= [[NSMutableDictionary alloc]initWithObjects:Yogesh forKeys:userdata];
NSMutableDictionary * dic1=[[NSMutableDictionary alloc]initWithObjects:sabari forKeys:userdata];
NSMutableDictionary * dic2=[[NSMutableDictionary alloc]initWithObjects:rajesh forKeys:userdata];
NSMutableDictionary * dic3=[[NSMutableDictionary alloc]initWithObjects:Ramya forKeys:userdata];
/* NSLog(@"%@", dic);
NSLog(@"%@", dic1);
NSLog(@"%@", dic2);*/
NSMutableArray * arraylist=[[NSMutableArray alloc]initWithObjects:dic,dic1,dic2,dic3, nil];
NSLog(@"Array = %@", arraylist);
NSLog(@"user entered value %d", _ccNumber.text.intValue);
NSLog(@"pin number %d ",_pin.text.intValue);
for(int i = 0; i< [arraylist count]; i++){
NSMutableDictionary *dictionary= arraylist[i];
// NSLog(@"userdata is [%d] %@",i,[dictionary objectForKey:@"Pinnumber"]);
NSInteger a;
NSInteger vx;
NSString *b;
NSString *str;
a = (self.ccNumber.text.integerValue);
vx = (self.pin.text.integerValue);
b = ([dictionary objectForKey:@"CreditcardNumber"]);
str = ([dictionary objectForKey:@"Pinnumber"]);
NSInteger c = [b integerValue];
NSInteger d = [str integerValue];
if(a == c && vx == d){
NSLog(@" user data is [%d] Name: %@",i,[dictionary objectForKey:@"Name"]);
NSLog(@" user data is [%d] Card Number: %@",i,[dictionary objectForKey:@"CreditcardNumber"]);
NSLog(@" user data is [%d] Pin Number :%@",i,[dictionary objectForKey:@"Pinnumber"]);
NSLog(@" user data is [%d] Active: %@",i,[dictionary objectForKey:@"Active"]);
}else{
NSString *DataStatus= @"Invalid Card Number";
self.dataStatusLbl.text = DataStatus;
NSLog(@"%@",DataStatus);
}
}
}
@end
我在使用xcode 12.4时遇到了这种情况,需要在一个objective-c项目中使用现有的C++类“CppModule”。以下是我的解决方法。
#if defined __cplusplus
declarations
#endif
然后字符串变量声明又出现了编译器错误:未知的类型名称'string';你是不是想说'std::string'?通过以下方式解决了这个问题:
#include <string>
using namespace std;
在module.h文件中包含C++头文件:
#include < CppModule.hpp>
第四点:对我来说有点奇怪的是,在 module.h 文件中,“CppModule” 不被识别为已知类型,因此您无法在模块的 module.h 中声明该类型的变量或属性,但在 module.m(m) 文件中它是一个已知类型。在 module.mm 文件中,在 @implementation 后添加以下内容:
static CppModule *module_cpp;
现在你可以在 module.mm 的 init 中调用 C++ 模块的初始化器,例如:
module_cpp = new CppModule(parameters);
而C ++模块仍可通过该静态module_cpp *指针访问。
CppModule::Result r = module_cpp->CppMethod();
看起来完全正常!
如果有人能解释第4点的奇怪之处,我会很感激。
我需要的模块只是做一些复杂(数字)计算,而我又不想将那些代码转换为 Objective-C。