Objective c library with c interface - c++

I have run into a problem... I'm trying to use QTKit in an application that we have at work. The only problem with that is the app is written in C++, not Obj-C. I have looked through Apple's documentation for answers, but I haven't found anything useful.
Basically what I'm looking to do is write a single controller class in Obj-C that has its methods exposed through a C interface to my app. I've written all that code already, but when I try and link it to even a sample C++ app, it finds the Obj-C symbols in the lib and complains about them being there. I thought about hiding the symbols using compiler flags, but I saw in Apple's docs that Obj-C isn't affected by that, since classes and messages are bound by the runtime and not the linker.
Has anyone successfully done this?
Thanks,
Robbie

You can use QTKit from within your C++ application by using Objective-C++:
Rename the files that access QTKit from .cpp to .mm. This does not change anything in your existing code but you can then use Objective-C from within these files.

Related

Using Cocoa static library built in c++, some ObjC code tries to rebuilt it in OC

I am programming in Xcode in ObjC using a Cocoa static library built in c++ (built by me). For the library project, I made one public header(.hpp) that includes all the other header files(.hpp). Then in the ObjC project, I wrote a wrapper code(.hpp and .mm) to play as the interface, so it includes the public hpp header. To access the library, I then include the wrapper code in a normal m file. I believe all of these followed the tutorials, as it worked well for a few weeks.
However, after doing something stupid yesterday, the compiler for the ObjC project started to insist on building all the headers in ObjC. It first had problems with openCV packages in the c++ library, producing errors saying thoses are supposed to be built in c++ (as shown below). Even if I removed the openCV, the compiler cannot find any standard c++ libararies. I tried renaming the .hpp's to .h but it did not work.
Any suggestions on what I did wrong and how I can fix this?Much appreciated!
()
Your errors are coming from compiling ImageProcessor.m. .m is the extension Obj-C files, so the compiler will try to compile it, and everything it includes as Obj-C.
I'd suggest renaming it to ImageProcessor.mm.
After learning more about header files, I realized what I did wrong: I included every header in the interface, so they are re-built every time outside the library, even if they are referenced by none-c++ code. The solution is to separate the interface header with other headers in the library completely.

Compiling python into a shared library

I have a bunch of python code that I would like to "compile" into a shared library with a C interface that can be linked with other C/c++ programs and work without depending on too many other libs (perhaps python and some other dlls but they should all be included into a directory with the final lib).
I don't really want to rewrite the python code into C++ for this. I can of course, but it would be best to have a standalone lib that can be used like a dll/so lib.
I have tried cython and wanted to compile python to C and then just compile C code into a dll but that doesn't seem to work quite yet (I haven't been able to make it work flawlessly yet). And then I also tried bbfreeze - but does bbfreeze support creating an .so file? Wasn't able to find out how to do it. Does anyone know?
Do you know of any other options that are more straightforward? the python code only needs to be compiled once. And best of all would be if it creates a single .so file no matter how big it is that just works without too many dependencies.
You can use Python as a library from inside your C++ application: it's called the Python/C API.
The idea is that you initialize your own interpreter, then you load a script in it. You can expose your C++ objects through global variables or modules inside the Python interpreter for your code to interact with, your you can just run Python functions directly from your C++ code.
Now, I understand that you might want to have your Python scripts embedded inside the shared library: this is not necessarily an easy task, with the traditional GNU toolchain. There are multiple techniques to achieve this, but none is official, and all seem way too complicated as opposed to just having the script in an external file.
If your goal is to hide the scripts from the end-user, you could sign them or encrypt them with a private key and embed the public key inside your library, but keep in mind that the key can easily be retrieved by anyone with enough motivation.

Is there a simple way to add a C++ object to an existing Objective-C Cocoa application

I'm struggling to figure out how to add a C++ class to a Cocoa application I'm writing.
I understand that by default Cocoa applications are compiled as Objective-C, and that Objective-C is a superset of C not C++.
I've tried setting the file types on my Objective-C classes to Objective-C++ Source and renaming them as .mm files but I'm still getting errors for my C++ class declaration.
Is there a simple/straightforward way to include existing c++ sources in a cocoa project? Or is should I just re-write my C++ objects in objective-c?
Update:
Ok it turns out that I was sort of wrong. When I tried to compile the project using Objective-C I was getting the errors:
Unknown type name class did you mean Class
Then when I change the Cocoa sources to Objective-C I'm getting a completely different error. So this issue is resolved.
Is there a simple/straightforward way to include existing c++ sources
in a cocoa project? Or is should I just re-write my C++ objects in
objective-c?
That's exactly what Objective-C++ lets you do -- you can use C++ objects and Objective-C object together. Bear in mind that you still need to use Obj-C syntax to send messages to Obj-C objects, and C++ syntax to call methods of C++ objects. But if you do that, your C++ and Objective-C objects should play together very nicely. If you're still having trouble, there may be some specific issues that we can help you with; edit your question to include the specific errors and the code that's causing them.

Wrapping C++ library in XCode

I need some help with wrapping C++ libraries in XCode.
What I want to achieve is to create new library in XCode, import C++ library (I have .a and .h files), wrap it to Obj-C so I can import that library to MonoTouch.
The reason why I do it round way is that when I try to import C++ lib into MonoTouch, because of name mangling I keep getting WrongEntryPoint exceptions. Correct me if I'm wrong but there is no way for me to find out mangled names, which depends on compiler.
Thank you in advance
Correct me if I'm wrong but there is no way for me to find out mangled names, which depends on compiler.
Technically you could. Many compilers share the same mangling syntax, maybe the most useful and long-lasting gift from Itanium ;-)
However it will bring it's own pain (e.g. non-primitive types, other compilers) and maintenance issues as you update your C++ code.
You'll better served by:
writing an ObjectiveC wrapper and use MonoTouch's btouch tool to generated bindings;
writing a C wrapper and using .NET p/invoke to call your code;
The choice it yours but if you think about reusing the C++/C# code elsewhere (e.g. Mono for Android) then using C and p/invoke will be reusable.
I would definitely recommend going the route of wrapping the library in an Obj-C library and using btouch to import the library into MonoTouch. I have recently done this for a C++ library that implemented a Sybase database engine. If you look at my questions you will find quite a few pertaining to wrapping C++ libraries as I posted a few times regarding issues I encountered.
Specifically, you can look at these questions:
Linking to a C++ native library in MonoTouch
Wrapping a C++ library in Objective-C is not hiding the C++ symbols
Application with static library runs on simulator but not on actual device
Undefined symbols when linking PhoneGap static library in MonoTouch
Linker options 'Link all assemblies" and "Link SDK assemblies only" causes undefined symbols in 3rd party static library
I would also recommend, if you are going to go the route of an Obj-C wrapper, that you get btouch to output code and include that in your project rather than including a dll from btouch. From my experience, the code worked more reliably than the dll, although the issues with the dll may have been resolved by now. But take a look at this question regarding the btouch issue:
Exception System.InvalidCastException when calling a method bound with btouch that returns an object. MonoTouch bug?
If you have specific questions/problems in building the Obj-C wrapper then ask them here and post some code and I am sure that I or other members of the community would be able to help you with it.
Bruce, as you assumed, I have problems with wrapping C++ code. After hours and hours of reading and trying, I couldn't wrap the C++ code.
Anyway, I managed to create a simple Obj-C library made of some dummy class, and then import it into another library. That worked fine. However, following same pattern, I included C++ .a file along with .h file (I'm not sure whether .h is mandatory because we can link header files in build options, right??) and when I compiled it, it went fine, the build succeeded, but XCode didn't produce new .a library.
I added linker flags: -ObjC -lNameOfLib
Does C++ Standard Library Type in Build - Linking has to be Static? And Symbols Hidden By Default as well?
It would be great if we could write step-by-step tut, since there are tons of various instructions, but I haven't been able to push it through the end.
I'm confused a bit..
Thank you guys...

Building C++ source code as a library - where to start?

Over the months I've written some nice generic enough functionality that I want to build as a library and link dynamically against rather than importing 50-odd header/source files.
The project is maintained in Xcode and Dev-C++ (I do understand that I might have to go command line to do what I want) and have to link against OpenGL and SDL (dynamically in SDL's case). Target platforms are Windows and OS X.
What am I looking at at all?
What will be the entry point of my
library if it needs one?
What do I have to change in my code?
(calling conventions?)
How do I release it? My understanding
is that headers and the compiled
library (.dll, .dylib(, .framework),
whatever it'll be) need to be
available for the project -
especially as template functionality
can not be included in the library by
nature.
What else I need to be aware of?
I'd recommend building as a statc library rather than a DLL. A lot of the issues of exporting C++ functions and classes go away if you do this, provided you only intend to link with code produced by the same compiler you built the library with.
Building a static library is very easy as it is just an collection of .o/.obj files - a bit like a ZIP file but without compression. There is no need to export anything - just include the library in the list of files that your application links with. To access specific functions or classes, just include the relevant header file. Note you can't get rid of header files - the C++ compilation model, particularly for templates, depends on them.
It can be problematic to export a C++ class library from a dynamic library, but it is possible.
You need to mark each function to be exported from the DLL (syntax depends on the compiler). I'm poking around to see if I can find how to do this from xcode. In VC it's __declspec(dllexport) and in CodeWarrior it's #pragma export on/#pragma export off.
This is perfectly reasonable if you are only using your binary in-house. However, one issue is that C++ methods are named differently by different compilers. This means that nobody who uses a different compiler will be able to use your DLL, unless you are only exporting C functions.
Also, you need to make sure the calling conventions match in the DLL and the DLL's client. This either means you should have the same default calling convention flag passed to the compiler for both the DLL or the client, or better, explicitly set the calling convention on each exported function in the DLL, so that it won't matter what the default is for the client.
This article explains the naming issue:
http://en.wikipedia.org/wiki/Name_decoration
The C++ standard doesn't define a standard ABI, and that's bad news for people trying to build C++ libraries. This means that you get different behavior from your compiled code depending on which flags were used to compile it, and that can lead to mysterious bugs in code that compiles and links just fine.
This extends beyond just different calling conventions - C++ code can be compiled to support or not support RTTI, exception handling, and with various optimizations that can affect the the memory layout of class instances, which C++ code relies on.
So, what can you do? I would build C++ libraries inside my source tree, and make sure that they're built as part of my project's build, and that all the libraries and the code that links to them use the same compiler flags.
Note that name mangling, which was supposed to at least prevent you from linking object files that were compiled with different compilers/compiler flags only mostly works, and there are certain things you can do, especially with GCC, that will result in code that links just fine and fails at runtime.
You have to be extra careful with vendor supplied dynamic C++ libraries (QT on most Linux distributions, for example.) I've seen instances of vendor supplied libraries that were compiled in ways that prevented certain things from working properly. For example, some Redhat Linux releases (maybe all of them) disabled exceptions in QT, which made it impossible to catch exceptions in main() if the exceptions were thrown in a QT callback. Fun.