As I heard it is possible to use C++ Code within an iPhone (Objective C) project, I want to use an encryption library which is written in C++. However, the library uses a C++ type struct which uses a constructor, that I can't get right.
The Struct looks like this:
struct SBlock
{
//Constructors
SBlock(unsigned int l=0, unsigned int r=0) : m_uil(l), m_uir(r) {}
//Copy Constructor
SBlock(const SBlock& roBlock) : m_uil(roBlock.m_uil), m_uir(roBlock.m_uir) {}
SBlock& operator^=(SBlock& b) { m_uil ^= b.m_uil; m_uir ^= b.m_uir; return *this; }
unsigned int m_uil, m_uir;
};
full source is available here: http://www.codeproject.com/KB/security/blowfish.aspx
what's the easiest way to get around that issue?
I've read the article about using c++ code on apple's developer site, but that didn't help much.
It's definitely possible and the trick is extremely simple: when you are going to use C++ code in your Objective-C++ applications, name your files .mm instead of .m.
So if you have YourViewController.h and YourViewController.m, rename the latter to be YourViewController.mm. It will cause XCODE to use C++ compiler instead of C compiler with your Objective-C++ code.
YourViewController.mm:
- (void) yourMessage {
// will compile just fine and call the appropriate C++ constructor
SBlock sb(1,1);
}
Just change the filename extension of your .m file to .mm and include the C++ headers. Wow, I type too slow, lol.
Related
I have some dynamic libraries making available over 200 functions via C calling conventions. I have no access to the source. I'd like to provide these as functions callable by Swift.
Currently I am making each function from the dylibs available via code like this:
public func mainInit() -> Int64 {
let dllMainInitPointer = getFunctionPointer(libHandle, "DllMainInit")
typealias DllMainInitFunction = PtrDllMainInit
let dllMainInit = unsafeBitCast(dllMainInitPointer, to: DllMainInitFunction.self)
return dllMainInit()
}
where PtrDllMainInit is obtained by Swift interpreting the C function prototypes in the header file, in this case:
typedef int64_t (*PtrDllMainInit)(void);
. . .
extern PtrDllMainInit DllMainInit;
which works. But (a) it returns the result of the function, and I'd rather it return the function itself, so it can be called independently, and (b) every use repeats executing the boilerplate code.
It seems that this boilerplate, in every function, could possibly be factored out. (I already factored, behind getFunctionPointer, calling dlsym and checking for missing symbols). Most of the dylib functions are generally more complex than this example, having multiple parameters; writing 200+ functions, like above, is time consuming and prone to error.
Ideally, I'd like a way auto-generate assignments that provide the Swift functions, using the dylib handle, the symbol name, and the C prototype; something like the following:
dllMainInit = magicFunction(libHandle, "DllMainInit", PtrDllMainInit)
In addition to factoring out repetition, one-liners (or, maybe two-liners) like this can be generated simply by processing the header file into this form.
Ultimately, allowing something of this form in the C headers:
typedef int (*PtrProp2)(int64_t key, double time, double llh[3]);
to be converted to a Swift function (closure?), and invoked, thusly:
let prop2 = magicFunction(libHandle, "DllProp2", PtrProp2)
. . .
prop2(id, hours, &vector)
This is a bit tangled, I hope I've explained it well enough.
Edit: Well, this works for simple function I started with:
public func mainInit() -> () -> Int64 {
unsafeBitCast(getFunctionPointer(libHandle,
"DllMainInit"),
to: PtrDllMainInit.self)
}
The parameters of the returned closure can be derived from the .h file. I'll see if this mechanism hold up for more complications.
When I try to call libjpeg’s jpeg_create_decompress() function, I get
/usr/include/x86_64-linux-gnu/jconfig.h:8:34: error: invalid suffix '.0' on floating constant
#define LIBJPEG_TURBO_VERSION 1.5.0
^
.../main.swift:49:5: error: use of unresolved identifier 'jpeg_create_decompress'
jpeg_create_decompress(&info)
^~~~~~~~~~~~~~~~~~~~~~
CJPEG.jpeg_CreateDecompress:1:13: note: did you mean 'jpeg_CreateDecompress'?
public func jpeg_CreateDecompress(_ cinfo: j_decompress_ptr!, _ version: Int32, _ structsize: Int)
^
<unknown>:0: error: build had 1 command failures
Now, looking inside jpeglib.h I see
/* Initialization of JPEG compression objects.
* jpeg_create_compress() and jpeg_create_decompress() are the exported
* names that applications should call. These expand to calls on
* jpeg_CreateCompress and jpeg_CreateDecompress with additional information
* passed for version mismatch checking.
* NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
*/
#define jpeg_create_compress(cinfo) \
jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_compress_struct))
#define jpeg_create_decompress(cinfo) \
jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
(size_t) sizeof(struct jpeg_decompress_struct))
EXTERN(void) jpeg_CreateCompress (j_compress_ptr cinfo, int version,
size_t structsize);
EXTERN(void) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version,
size_t structsize);
The jpeg_create_decompress isn’t available, probably as stated in the documentation:
Complex macros are used in C and Objective-C but have no counterpart in Swift. Complex macros are macros that do not define constants, including parenthesized, function-like macros. You use complex macros in C and Objective-C to avoid type-checking constraints or to avoid retyping large amounts of boilerplate code. However, macros can make debugging and refactoring difficult. In Swift, you can use functions and generics to achieve the same results without any compromises. Therefore, the complex macros that are in C and Objective-C source files are not made available to your Swift code.
But without this macro, how do I use libjpeg with Swift?
I don't see a way around redefining them in Swift, for example:
class JPEGLibWrapper {
class func jpeg_create_decompress(cinfo: j_decompress_ptr) {
jpeg_CreateDecompress(cinfo, JPEG_LIB_VERSION, MemoryLayout<jpeg_decompress_struct>.size)
}
}
Or in Objective-C:
#interface JPEGLibWrapper : NSObject
+ (void) jpeg_create_decompress:(j_decompress_ptr)cinfo;
#end
#implementation JPEGLibWrapper
+ (void) jpeg_create_decompress:(j_decompress_ptr)cinfo {
jpeg_create_decompress(cinfo);
}
#end
(Better naming could be used...)
EDIT I just noticed you're using Swift on Linux, correct? I don't know how the Swift–C bridging is done on Linux but I guess could do something similar to the Objective-C code but in a C file.
The advantage of declaring an Objective-C or C method/function over doing it in Swift is that in the former you're actually using the complex macro, therefore avoiding (mis)translating it. You just declare a wrapper method/function around it and expose it to Swift.
Source:
https://www.andrewcbancroft.com/2015/01/29/converting-complex-objective-c-macros-swift-functions/
https://medium.com/#YogevSitton/from-objective-c-to-swift-use-complex-define-macros-in-swift-28cdff464fc7
I've just found out that Swift's private access modifier is file level, as stipulated in the docs under "Access Levels":
Private access in Swift differs from private access in most other languages, as it’s scoped to the enclosing source file rather than to the enclosing declaration. This means that a type can access any private entities that are defined in the same source file as itself, but an extension cannot access that type’s private members if it’s defined in a separate source file.
So this means the following code will compile when the types are in the same file:
class FirstType {
private var privateProperty: String = ""
}
class SecondType {
private let firstType = FirstType()
func messWithFirstType() {
firstType.privateProperty = "👻" // this compiles and works!
}
}
As far as I can see, this breaks encapsulation completely. On the other hand, it might be nice to have some related types grouped together in the same file for readability, especially if the related types are tiny, like enums.
Private extensions are an exception because they are extending the same type the file is meant to contain. And private extensions do bring some nice things.
Are there any other reason, apart from facilitating private extensions, for the file scope private access modifier to be in Swift?
It isn't clear to me why private was originally implemented with regard to files, but rest assured that the Swift folks know this is not the only possible meaning of private and that it isn't ideal for some purposes, and are working to change it. There's already a proposal on the table, accepted for Swift 3, that will turn the current private into fileprivate and add a new level of private that will be scoped to the type rather than the file. You can expect to see this become part of Swift 3 in the very near future.
When you wonder about anything that seems "weird" in Swift, most of the time the answer is "because of Objective-C".
For some perspective, I consider 3 access level common to many modern programming languages:
private: only accessible to the class in which it is defined.
protected: only accessible to the class in which it is defined and its subclasses.
public: accessible to any outside program.
Let's take one step further back, to the world of C. C has no access modifier whatsoever, not being an OOP language. However, in reality, it's closer to having a private / public system. If you want other programs to know your symbols (functions, macros, data types, etc.), you define them in your header (.h) file. If not, you define them in your source (.c) file or a private header file. Whatever program interested in your symbol will include the corresponding header file:
#include "foo.h"
This #include is no more than a compiler-assisted copy & paste. The compiler copies all the symbols in foo.h and redeclare them in your source file.
Since Objective-C is a strict superset of C, every valid C program is also a valid Objective-C program. Objective-C continues this tradition: declare your public methods in the header file, keep private methods declaration to the implementation file:
// ------------------------------------------
// MyClass.h
// ------------------------------------------
#interface MyClass: NSObject
- (void) publicMethod;
#end
// ------------------------------------------
// MyClass.m
// ------------------------------------------
#import "MyClass.h"
// Declare your private methods here.
// You can move this to a separate file, i.e. MyClass+Private.h if you want
#interface MyClass()
- (void) privateMethod;
#end
#implementation MyClas
- (void) publicMethod () { ... }
- (void) privateMethod() { ... }
#end
So at glance, Objective-C seems to inherit C's system of public / private declarations. However, Objective-C is a very dynamic language. You can query its runtime for all methods to a class, private or public. Access control in Objective-C is more about "use what I tell you in the documentation" rather than "this method is off limit to you".
This poses a paradox: how do you implement protected in Objective-C? It has no good answer for that. One common pattern is to move all protected methods into a separate declaration file and import them into the main class and subclass's implementation:
// ------------------------------------------
// MyClass+Protected.h
// ------------------------------------------
#interface MyClass (Protected)
- (void) protectedMethod;
#end
// ------------------------------------------
// MySubClass.m
// ------------------------------------------
#import "MyClass+Protected.h"
...
Swift simply carries on that tradition, for better or worse. There is an accepted proposal to change this in Swift 3. If anything, Chris Lattner and the Swift team has shown little affinity for the past and the legacies of C. You can see evidence of that in Swift 2.2 with the removal of ++ and C-style for loops.
I just pulled the latest doxygen from github, compiled it on my Mac, and ran it on a mix of Objective-C and C++ in .mm files. For some of the the C++ classes, the output HTML makes the methods look like Objective-C. For example, code like:
void Thing::foo(int x)
Is shown in the HTML like:
- (void) foo (int) x
Any way to fix this?
Update
It appears that a forward declared Objective-C class causes a problem. For example, something like this, in a .h file:
#class NSMutableString;
...
class Thing {
public:
int foo(double x);
}
Causes it to render the Thing methods like Objective C. I cut that one line #class NSMutableString and it renders correctly like C++ functions.
C++ classes in .mm files are rendering like Objective-C all the time.
I've been declaring private methods in class extensions, according to Best way to define private methods for a class in Objective-C.
But, I just realized that, in Xcode 4, if I leave out the declaration of a private method altogether and just implement it, the app compiles and runs without warning or error.
So, should I even bother declaring private methods in class extensions?
Why should we have to declare methods anyway? In Java, you don't... neither in Ruby.
A method definition only needs to be defined if the caller is declared before the method. For consistency I would recommend defining your private methods in the extension.
-(void)somemethod
{
}
-(void)callermethod
{
//No warning because somemethod was implemented already
[self somemethod];
}
-(void)callermethod2
{
//Warning here if somemethod2 is not defined in the header or some extension
[self somemethod2];
}
-(void)somemethod2
{
}
This answer has already been correctly answered by Joe for Xcode prior to v4.3. However, in v4.3 and above, not only do private methods not need to be declared, but declaration order is now irrelevant. For details, see:
Private Methods in Objective-C, in Xcode 4.3 I no longer need to declare them in my implementation file ?
This will compile and run fine without declaration:
- (void)foo {
}
- (void)bar {
[self foo];
}
But last I checked, this will give a warning:
- (void)bar {
[self foo];
}
- (void)foo {
}
In other words, it's just like in C: a declaration is not necessary if the definition comes before any use. C requires this to avoid having to add an extra pass to the compiler (one to find the functions and then one to actually parse them). As for whether you should declare them when not necessary, it's really up to the style of the codebase you're working with.
As for other languages that don't require declarations, some just go ahead with the extra pass, while others don't need to know the number and types of the arguments or the return type at compile time (they look up functions at runtime instead, or they don't have strongly-typed variables to begin with so it doesn't "matter") so they can just skip it.