How do you call a C function from C++ code in the iPhone? - iphone

I added the line extern "C" void perlinTest(void); to a C++ header along with the include of the c header file hoping that was all I needed but the compiler complains:
Undefined symbols for architecture i386:
"perlinTest()", referenced from:
CreateRenderer3(IResourceManager*) in Renderer.o

Your C++ code needs to be aware that the function is a C function. To do so, you need to declare it this way:
extern "C" [prototype];
A realistic example for your situation would be:
extern "C" void perlinTest();
The reason for this is that C++ function names are mangled to something that tells about the types of the parameters. At the lowest level, this is what allows overloading: it never really is legal to have two visible symbols that share the same name, so C++ allows them by embedding markers that indicate the types of the parameters in the function names. For instance, void perlinTest() gets mangled as _Z10perlinTestv on my Lion box with g++ (and probably clang++), though this is ABI-specific and will not necessarily be the same on other platforms.
However, C doesn't support overloading, and functions aren't subject to name mangling, so when your C++ code tries to call one, it needs to know that it must not use a mangled name. This is what extern "C" tells the compiler.
If your header files need to be readable from both C and C++, the common practice is to wrap them in an extern "C" block (extern "C" { /* declarations */ }) itself wrapped in an #ifdef __cplusplus preprocessor directive (so the C code doesn't see the extern "C" code).
#ifdef __cplusplus
extern "C" {
#endif
/* header body */
#ifdef __cplusplus
}
#endif

If it is not a library, you do not need any extern C. Iwould be turning to the .c file extensions and how your compiler is configured to recognize it (looks like not as .c code)

Have you actually implemented void perlinTest(void) anywhere?
Initially, you'll likely be able to merely declare the function without actually having to implement it. If none of your other classes/objects actually call perlinTest(), Xcode will gladly build and run your app, and not issue any errors. Since perlinTest() isn't actually referenced from anywhere, it doesn't care that the function isn't actually implemented.
As soon as you attempt to call perlinTest() from one of your other classes (like from CreateRenderer3(IResourceManager*) in Renderer.o), the linker will want to make sure that symbol can be resolved, and if you haven't actually implemented a barebones definition of it (see below), then you'll likely get an error like the one you got.
A minimal implementation like the following should prevent the linking error:
void perlinTest(void) {
}

One trick you can use to debug this is to introduce an intentional error in your perlinTest() function. Then build your app and see if the compiler reports the error. If the app compiles anyway, then your problem is that the file that has this function is not part of the target you are building.
Also note that the error that you pasted is for a i386 architecture, so it can't be iPhone. You are probably building for the iPhone simulator instead.
Edit: next step would be to check that the link command issued by Xcode includes the .o that has the C function. If it does, then you should dump the contents of the .o file with the nm utility, to see what the function name looks like in the .o.

Related

Using compiler variables in Swift

In Objective-C I had a bunch of compiler flags set in Build Settings -> Other C Flags that were being used in the code. For instance:
Flag => -DPortNumber = 1
And in code I was able to access it by #(PortNumber)
This doesn't work in Swift, and I'm not able to find an answer.
The -D flag to C compilers defines a preprocessor macro. There are no preprocessor macros in Swift. So if you're looking to do something like:
// compile with -DPORT_NUMBER 31337
var port = PORT_NUMBER // error
... you can't. Swift is designed for source code to be syntactically complete before compilation. If you could switch out blocks of it at build time, you'd break the ability of the toolchain to help verify that your code is correct. (Partly this is because preprocessor macros in C are textual replacement: you can use them to rewrite any part of the language, not just fill in values for variables.)
The Swift compiler does have a -D flag, but its use is more limited: you can use it for build configurations only. So, if you wanted to do something like the following, you'd be cool:
// compile with -DUSE_STAGING_SERVER
#if USE_STAGING_SERVER
var port = 31337
#else
var port = 80
#endif
Note that unlike C, everything inside an #if block needs to be syntactically complete. (For example, you can't put just the declaration line of a func in an #if block and leave the function body outside the conditional.)
Of course, this doesn't help you if you want to have a configuration value set at compile time be used in your code. For that, I'd recommend alternate approaches. Xcode can still do textual substitution in resource files, like property lists. (Note that the Info.plist that comes with your app is full of things like $(TARGET_NAME), for example.) So, you could include a bundle resource with your app whose contents are populated at compile time according to your project settings, then read your port number from that.

Reimplimenting a DLL method variable with C++ in visual studio at ABI level

I have a third party DLL in C++ that I'd like to replace with one I've made myself...
This is a clean room type exercise just for learning purposes ; and I am hoping to make a replacement DLL that can be used with programs linked against the original DLL -- without recompiling the applications.
I am using the same visual studio compiler version (9) used to make the original DLL, but I do not have the original source code for the DLL.
The DLL consists of a C++ class, and some extern "C" functions to handle constructor/destructors, so that all memory management is isolated to the DLL.
I used dependency walker to inspect the original DLL, and demangle/undecorate the linker symbols -- and have attempted to write prototypes for the class and methods ; and then I wrote a python script to take the object code compiled from my class -- and make a .def file that chooses the closest mangled symbols from MY obj code compared against the original DLL exports; ( Allows some qualifier variations, but not name variations ) and then I build a DLL from my obj code using that .def file to have an identical ABI ordering in the DLL.
I am at the stage where dependency walker can not tell the difference between my DLL and the original when it comes to listing the types -- although there are small differences in several of the mangled names that I would like to resolve...
One member is very troublesome to figure out as it is not a function, but supposedly member data eg: a decorated ?pzSambaAddress#HWInterface##2PBDB shows up as:
char const * const HWInterface::pzSambaAddress ; // in dependency walker
And I'm not sure if dependency walker is decoding the mangling wrong or not, because
I can't figure out how to implement anything even remotely like this in my header file which would export a symbol to an .obj file, let alone to a DLL.
What kinds of definitions could create something like that?
If I type it in (as shown above) to my header file, it's a constant string -- therefore I'm thinking it has to be initialized in the constructor methods, something like this:
HWInterface::HWInterface(HWInterface const & iface) : pzSambaAddress("dummy") {
std :: cout << this -> pzSambaAddress; // access it, to force compiler
}
But when I compile that, pzSambaAddress, does not show up in the obj file at all.
Obviously because it's not an allocated memory location prior to class instantiation.
eg: dumpbin /SYMBOLS HWInterface.obj | grep "pzSam" finds nothing.
I could add the static keyword to the definition of pzSambaAddress and initialize it exactly once for the whole class.
char const * const HWInterface::pzSambaAddress="a samba name constant.";
The name then mangles to: ?pzSambaAddress#HWInterface##2QBDB
But dependency walker doesn't say it's static... Nor is mangled ##2QBDB quite ##2PBDB... and that will also mean that I can also no longer initialize individual instances with constructors.
HWInterface.cpp(25) : error C2438: 'pzSambaAddress' : cannot initialize static class data via constructor
So Q1: Is a static constant the cause of the exported symbol, and dependency walker just doesn't say "static" -- or are there other ways it could be generated / initialized ?
Secondly:
Is there anything better at demangling, and giving information on esoteric qualifiers?
When I run dumpbin on an object file, I get all kinds of qualifiers that dependency walker doesn't show (on other symbols, not the example we've been talking about).
dumpbin.exe /symbols myOwnFile.obj
But as I don't have the obj file for the original DLL, nor the .lib, that switch doesn't work. Running dumpbin.exe /symbols on the DLL gives me nothing.
Running dumpbin.exe /exports on the DLL merely gives me the mangled names.
There is also a VC++ console application "undname.exe", but often it doesn't undecorate the name passed on the command line at all, but gives most of the name back still mangled.
I looked around a lot on the web, but am finding only partially accurate/incomplete information, which wasn't enough to solve the problem I just showed.
Wikipedia on mangling names
Any ideas of where to find a more verbose/accurate demangler program for visual C++ ?
class HWInterface {
public:
__declspec(dllexport)
static char const * pzSambaAddress;
};
char const* HWInterface::pzSambaAddress = "hello";
Then:
C:\temp>cl /LD test.cpp
...
C:\temp>dumpbin /exports test.dll
...
Dump of file test.dll
...
ordinal hint RVA name
1 0 00008000 ?pzSambaAddress#HWInterface##2PBDB
You can use the undname utility included with MSVC to decode mangled names:
C:\temp>undname ?pzSambaAddress#HWInterface##2PBDB
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "?pzSambaAddress#HWInterface##2PBDB"
is :- "public: static char const * const HWInterface::pzSambaAddress"
However, you'll note that undname says that there should be an extra const in there. As you saw, adding that extra const gets you a slightly different mangled name (with a 'Q' instead of a 'P' near the end:
Using static char const * const instead of static char const * produces ?pzSambaAddress#HWInterface##2QBDB
undname imports a function from the C runtime, _unDNameEx, that I assume is used to demangle names (and I assume that Dependency Walker uses it, too - apparently via an interface in DBGHELP.DLL). Looks like there's a bug in the demangler.
The GNU tools have a similar utility, c++filt, to decode g++ mangled names.

Compiling C with Objective-C and duplicate symbol linker error (iPhone related)

I have the following file testf.h:
#ifndef TESTF_H_
#define TESTF_H_
int test(int what){
return what;
}
#endif
I included/imported it in TestAppDelegate.h (which is used for other .m files in my xcode project). I get a duplicate symbol error. If I included/imported testf.h in a .m file that is never included/imported in other files then it works fine. So it seems like the #ifndef/#define/#endif has no effect. Is there anyway to go around this?
Thanks
This is a function definition, it belongs in a c, cpp or m file.
This popular trick with #defines will protect you from compiler errors (typically to survive circular #include dependencies. ) It will not protect against a linker error. This is exactly why people put declarations in h files and definitions in c (or m) files.
Including function definitions (as opposed to declarations) in header files is generally a bad idea and now you know why. You want two separate files, the header would look like this:
#ifndef TESTF_H_
#define TESTF_H_
extern int test(int);
#endif
And then a .c file (or possibly a .m file if you want to use Objective-C rather than plain C) like this:
int test(int what) {
return what;
}
The header file will let the compiler know what test is, what it returns, and what arguments it should take; that's enough information for the compiler to arrange a call to test; that's actually more information than the compiler needs but some of us like our compilers to do some error checking. The C source file will (after being compiled into a object file) let the linker know what code the test symbol resolves to.
Right now you're ending up with multiple globally visible instances of the test symbol, one for every file that has included your testf.h.
The other option, for a simple function, is to declare it inline:
inline int cNorm(float _amp) {
return 42;
}

Need clarification on what's going on when linking libraries in iOS

This is probably a totally noob question but I have missing links in my mind when thinking about linking libraries in iOS. I usually just add a new library that's been cross compiled and set the build and linker paths without really know what I'm doing. I'm hoping someone can help me fill in some gaps.
Let's take the OpenCV library for instance. I have this totally working btw because of a really well written tutorial( http://niw.at/articles/2009/03/14/using-opencv-on-iphone/en ), but I'm just wanting to know what is exactly going on.
What I'm thinking is happening is that when I build OpenCV for iOS is that your creating object code that gets placed in the .a files. This object code is just the implementation files( .m ) compiled. One reason you would want to do this is to make it hard to see the source code and so that you don't have to compile that source code every time.
The .h files won't be put in the library ( .a ). You include the .h in your source files and these header files communicate with the object code library ( .a ) in some way.
You also have to include the header files for your library in the Build Path and the Library itself in the Linker Path.
So, is the way I view linking libraries correct? If , not can someone correct me on this ?
Basically, you are correct.
Compiling the source code of a library produces one object file for each of the source files (in more than one, if compiled multiply times against different architectures). Then all the object files are archived (or packaged) into one .a file (or .lib on Windows). The code is not yet linked at this stage.
The .h files provide an interface for the functionality exposed by the library. They contain constants, function prototypes, possibly global declarations (e.g. extern int bad_global;), etc. -- basically, everything that is required to compile the code which is using the library.
.h files do not 'communicate' with object code in any way. They simply provide clues for the compiler. Consider this header file:
// library.h
extern int bad_global;
int public_func(int, const void*);
By including this file in your own code, you're simply telling the compiler to copy and paste these declarations into your source file. You could have written declarations for OpenCV library and not use the headers provided with it. In other words, you're asking the compiler to not issue errors about undefined symbols, saying "I have those symbols elsewhere, ok? Here are their declarations, now leave me alone!".
The header files need to be included in the search path in order for compiler to find them. You could simply include them via the full path, e.g. #include "path/to/file.h", or supply an -I option for your compiler, telling him where to look for additional headers, and use #include <file.h> instead.
When your code is compiled, the declarations in header files serve as an indication that symbols your code is using are defined somewhere. Note the difference between the words declaration and definition. Header files contain only declarations most of the time.
Now, when your code is compiled, it must be linked in order to produce the final executable. This is where the actual object code stored in the library comes into play. The linker will look at each symbol, function call, etc. in your object code and then try to find the corresponding definition for each such symbol. If it doesn't find one in the object code of your program, it will look the standard library and any other library you've provided it with.
Thus, it is important to understand that compilation and linkage are two separate stages. You could write any function prototypes at all and use them in your code, it will compile cleanly. However, when it comes to the linking stage, you have to provide implementation for symbols used in your code, or you won't get your executable.
Hope that makes sense!
The .a is the compiled version of the code.
The header files provided with a library are its public interface. They show what classes, methods, properties are available. They do not "communicate" with the binary code.
The compiler needs the headers to know that a symbol (a method name for example) is defined somewhere else. They are associated with the right "piece of code" in the library binary later during the "link" step.

Can a macro also generate a method name?

Is it generally valid that a macro is used to create a method name? I mean...actually it's just simple text replacement before the compiler actually runs, right?
Yes, it is valid; macro expansion occurs before the compiler even reads the code. The main limitation is that one cannot embed a preprocessor directive within a preprocessor directive. So, for example:
// This is ok:
#define PREFIX(X) this_name_is_prefixed_ ## X
// ...
- (void) PREFIX(doSomething):id;
// ...
// But this isn't:
#define IMPORT(X) #import X
IMPORT(<Foundation/Foundation.h>) // <= Don't expect this to work
With the exception of the "#import" directive, Objective-C's preprocessor is basically the same as the C preprocessor. (The "#import" is like "#include", except that #import implies include only once, so preprocessor guards are not required for headers that are included only with #import).
There is nothing that prevents that. It is even commonly used (though I don't know for the iphone), for instance, in device drivers implementation. In that case, macros are used to generate boilerplate code, and for this boilerplate to communicate with your code, you have to either guess the correct function names (not advised), or use generating macros, for example USB_ATTACH(uthum) to generate the signature of the attach method for the uthum driver.