I have added a c++ library .dylib to my objective c cocoa os x app. When I am trying call a function that I wrote into .dylib with my .header class I can't compile because I get the errors. In c+++ project all is correct, but into objective c no.
My viewController:
#import "myHeader.mm"
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
mean(5.8, 5.8);
}
My class header:
#ifdef __cplusplus
extern "C" {
#endif
//void donothing(void);
//double mean(double x, double y);
double mean(double x, double y);
#ifdef __cplusplus
}
#endif
The errors are:
Undefined symbols for architecture x86_64:
"_mean", referenced from:
-[ViewController viewDidLoad] in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
How can solve this? What is the correct form to add .dylib to my project?
Thanks!
Related
I am gearing up to use libdc1394 for camera capture on Mac OS 10.9/XCode5 and I am running into Apple Mach-O Linker Errors. I am working off of what seemed to be good instructions for libdc1394 and XCode, and was successful in locating libdc1394.dylib, including , and getting to hello world, which should mean everything is properly connected.
I am new to XCode Development so please be detailed in your answer if possible! I understand that this may have something to do with the targeting of the build.
The next step was to build a simple example (grab_color_image.c), but I am getting a ton of linker errors, starting with anything in void cleanup_and_exit(dc1394camera_t *camera), which I commented out:
void cleanup_and_exit(dc1394camera_t *camera)
{
// dc1394_video_set_transmission(camera, DC1394_OFF);
// dc1394_capture_stop(camera);
// dc1394_camera_free(camera);
// exit(1);
}
For example, uncommenting the first line above gives:
*Undefined symbols for architecture x86_64:
"_dc1394_video_set_transmission", referenced from: cleanup_and_exit(__dc1394_camera**) in main.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
Below I tried to move further in the program, leaving the stuff above commented out ...
The program below gives a similar error at d = dc1394_new ();: Undefined symbols for architecture x86_64:
"_dc1394_new", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
#include <iostream>
#include <dc1394/dc1394.h>
#include <stdio.h>
#include <stdint.h>
#include <dc1394/dc1394.h>
#include <stdlib.h>
#include <inttypes.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#define IMAGE_FILE_NAME "image.ppm"
/*-----------------------------------------------------------------------
* Releases the cameras and exits
*-----------------------------------------------------------------------*/
void cleanup_and_exit(dc1394camera_t *camera)
{
// dc1394_video_set_transmission(camera, DC1394_OFF);
// dc1394_capture_stop(camera);
// dc1394_camera_free(camera);
// exit(1);
}
int main(int argc, const char * argv[])
{
FILE* imagefile;
dc1394camera_t *camera;
unsigned int width, height;
dc1394video_frame_t *frame=NULL;
//dc1394featureset_t features;
dc1394_t * d;
dc1394camera_list_t * list;
dc1394error_t err;
d = dc1394_new (); // <-- THIS gives a linker error, the above stuff is fine
// if (!d)
// return 1;
// err=dc1394_camera_enumerate (d, &list);
// DC1394_ERR_RTN(err,"Failed to enumerate cameras");
// insert code here...
std::cout << "Hello, World!\n";
return 0;
}
As I mentioned before, I am altogether new to XCode development, and suspect it may have something to do with the "build target", but it's not totally obvious. Here is a snapshot of some basic info (sorry it is a bit blurry):
I needed to click the checkbox on target membership for libdc1394.dylib.
Clicking libdc1394.dylib on the left side of XCode brings up this on the right side. I needed to add target membership. Although in the initial part of the instructions #include worked, it didn't later because the dylib library wasn't linked to the project, and thus the symbols weren't defined for the linker. (or something like that ...)
I created a static library that includes the follow C++ files:
//TestClass.h File:
#ifndef TESTCLASS_H_
#define TESTCLASS_H_
using namespace std;
#include <string>
class TestClass
{
public:
TestClass();
virtual ~TestClass();
int sum(int x, int y) const;
string chain(const string& x, const string& y) const;
};
#endif /* TESTCLASS_H_ */
//TestClass.cpp File:
#include<iostream>
#include "TestClass.h"
TestClass::TestClass()
{
}
TestClass::~TestClass()
{
}
int TestClass::sum(int x, int y) const
{
return x+y;
}
//Test.cpp File:
string TestClass::chain(const string& x, const string& y) const
{
return x+y;
}
int main(int argc, char* argv[])
{
TestClass test;
cout << "1+1 = " << test.sum(1,1) << endl;
cout << "Dog+Cat = " << test.chain("Dog","Cat") << endl;
return 0;
}
I added
-x objective-c++
flag in "Compile Source" and
-lstdc++
flag in "Info.plist Other Preprocessor flags".
When I link my just created static library (with Objective C wrapper files), I receive the 4 follow errors, that I don't have any idea how to fix it:
Undefined symbols for architecture arm64:
"vtable for __cxxabiv1::__class_type_info", referenced from:
typeinfo for TestClass in libPredictionComplete.a(TestClass.o)
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"operator delete(void*)", referenced from:
TestClass::~TestClass() in libPredictionComplete.a(TestClass.o)
"___gxx_personality_v0", referenced from:
-[CppObject init] in libPredictionComplete.a(CppObject.o)
-[PredictionComplete init] in libPredictionComplete.a(PredictionComplete.o)
-[PredictionComplete chain::] in libPredictionComplete.a(PredictionComplete.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'll appreciate any ideas about.
From my experience, Xcode will fail to link against C++ libraries when there are no C++ sources present in the top-level project. This is also true in pure Obj-C projects as well where you are linking against static libraries that have C++ code.
A less invasive solution is to simply include an empty C++ source file in your project (here's an example cpp stub) that is "compiled" into the final .app binary. It actually doesn't emit any code, but it makes Xcode aware that there is C++ code present, causing C++ libraries to be linked in.
The advantage of this solution is it avoids modifying the project settings in Xcode, so no need to add special linker flags to force Xcode to do the right thing.
I fixed it when I added the "-lstdc++" compile flag to "other linker flags" section in the Swift Project itself and not only in the static library project with c++ files.
The -lstdc++ should be in "Other Linker Flags" (or OTHER_LDFLAGS). Note that that will only work if the "C++ Standard Library" is set to libstdc++.
Also of note is that Xcode is usually smart enough to include the standard C++ library if the target has any C++ source code in it, so you don't need to explicitly link to either libstdc++ or libc++.
You should have -x c++ rather than objective-c++. There is, however, no need to specify this flag if you name your C++ sorce *.cpp.
I'm trying to use libreDWG to open and understand some dwg files. I have installed it and at least got some of the test programs to run (even if they seg fault later on). Anyway, I have included a small header file in my project very similar to the simple example found here https://github.com/h4ck3rm1k3/libredwg/blob/master/examples/load_dwg.c There seems to be a general problem with data types (at least in the way I'm compiling it) meaning I've added a few casts of form (char*) to number of variables which previously trying to automatically convert (void*) and (unsigned char*) to type (char*) and got rid of those compiler complaints. But even still when I compile it like so
g++ xxx.c++ -L/opt/local/lib/ -lredwg -o program_name
I get the following error:
Undefined symbols for architecture x86_64:
"dwg_read_file(char*, _dwg_struct*)", referenced from:
load_dwg(char*)in ccN6HUqz.o
"dwg_free(_dwg_struct*)", referenced from:
load_dwg(char*)in ccN6HUqz.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I'm not sure what to do, I've fixed any problems in the source the compiler complains about and am linking to the relevant libraries with -lredwg (right? I haven't missed any?). My header file is just to test the functionality and looks like:
#include "suffix.c"
#include <dwg.h>
plan floor_plan;//temporary data structure defined elsewhere for now
void
add_line(double x1, double y1, double x2, double y2)
{
line_in temp;
temp.start.x=x1;
temp.start.y=y1;
temp.end.x=x2;
temp.end.y=y2;
floor_plan.lines.push_back(temp);
std::cout<<"LINE: :"<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<std::endl;
}
void
add_circle(double x, double y, double R)
{
// Yet to do
}
void
add_text(double x, double y, char *txt)
{
// Make something with that
}
int
load_dwg(char *filename)
{
unsigned int i;
int success;
Dwg_Data dwg;
dwg.num_objects = 0;
success = dwg_read_file(filename, &dwg);
for (i = 0; i < dwg.num_objects; i++)
{
Dwg_Entity_LINE *line;
Dwg_Entity_CIRCLE *circle;
Dwg_Entity_TEXT *text;
switch (dwg.object[i].type)
{
case DWG_TYPE_LINE:
line = dwg.object[i].tio.entity->tio.LINE;
add_line(line->start.x, line->end.x, line->start.y, line->end.y);
break;
case DWG_TYPE_CIRCLE:
circle = dwg.object[i].tio.entity->tio.CIRCLE;
add_circle(circle->center.x, circle->center.y, circle->radius);
break;
case DWG_TYPE_TEXT:
text = dwg.object[i].tio.entity->tio.TEXT;
add_text(text->insertion_pt.x, text->insertion_pt.y, (char*) text->text_value);
break;
}
}
dwg_free(&dwg);
return success;
}
What am I doing wrong? I believe libredwg is written in c. Is this the problem?
It seems that you are trying to link against a 32 bit library when you're on a 64 bit platform, like in this answer. Solution is to download (or build yourself from source) a 64 bit version of libredwg. Or alternatively add the "-m32" flag to your g++ command line - to build your whole app as a 32 bit executable.
EDIT : as you have found out, the problem is actually caused by trying to link C++ code with a C library without the following at the top / bottom of your code :
#ifdef __cplusplus
extern "C" {
#endif
// ... source code here
#ifdef __cplusplus
}
#endif
Basically this tells the compiler not to do C++ name-mangling - switching name mangling off allows linking between C and C++
just wanted to start some C++ and created these simple class:
Ellipsoid.h
#ifndef __Ellipsoid__Ellipsoid__
#define __Ellipsoid__Ellipsoid__
#include <iostream>
#include <cassert>
class Ellipsoid {
private:
double axisA;
double flatteningF;
public:
Ellipsoid() {};
Ellipsoid(double aIn, double fIn);
double getAxisA();
double getFlatteningF();
};
#endif /* defined(__Ellipsoid__Ellipsoid__) */
Ellipsoid.cpp
#include "Ellipsoid.h"
Ellipsoid::Ellipsoid (double aIn, double fIn) : axisA(aIn), flatteningF(fIn) {};
int main() {
std::cout << "bla";
Ellipsoid el = Ellipsoid(44.3, 32);
double test = el.getAxisA();
return 0;
}
as you can see nothing special here. i'm using xcode on osx10.8.
But when i run the programm i come to this error:
Undefined symbols for architecture x86_64:
"Ellipsoid::getAxisA()", referenced from:
_main in Ellipsoid.o
ld: symbol(s) not found for architecture x86_64
and i really can't figure out whats wrong. tried to set the architecture to 32 bit but this won't work neither
The definition of the Ellipsoid::getAxisA() function is missing. You must define somewhere. Right now you only have a declaration, not a definition. The definition could look something like this:
double Ellipsoid::getAxisA() { return axisA; }
And would live in Ellipsoid.cpp.
I've read a number of posts on this issue but I haven't found anything particularly helpful. I am trying to make a weldJoint when two sprites meet using a contact listener. I keep getting the following error:
Apple Mach-O Linker (Id) Error
"_touchingBodies", referenced from:
SubcContactListener::BeginContact(b2Contact*) in SubcContactListener.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here is my contact listener.
SubcContactListener.h:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Box2D.h"
#import <vector>
typedef std::pair<b2Body*, b2Body*> bodyPair;
typedef std::vector<bodyPair> thingsThatTouched;
extern thingsThatTouched touchingBodies;
class SubcContactListener : public b2ContactListener {
public:
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
};
SubcContactListener.mm:
#import "SubcContactListener.h"
void SubcContactListener:: BeginContact(b2Contact *contact) {
touchingBodies.push_back( std::make_pair(contact->GetFixtureA()->GetBody(), contact->GetFixtureB()->GetBody()) );
}
I added:
thingsThatTouched touchingBodies;
to the HelloWorldLayer.h interface.
Finally, in the tick method of the HelloWorldLayer.mm (after the timestep):
b2WeldJointDef weldJointDef;
b2WeldJoint *weldJoint;
for (int i = 0; i < touchingBodies.size(); i++) {
b2Body* bodyA = touchingBodies[i].first;
b2Body* bodyB = touchingBodies[i].second;
weldJointDef.Initialize(bodyA, bodyB, bodyA->GetWorldCenter());
weldJointDef.collideConnected = false;
weldJoint = (b2WeldJoint*)world->CreateJoint(&weldJointDef);
}
touchingBodies.clear();
Please help, I've been at it for a while.
extern thingsThatTouched touchingBodies;
Such extern variables must be defined as static C variables elsewhere, not instance variables.
In light of a better design, I recommend to scrap the extern variable and instead access the touchingBodies through the HelloWorldLayer by adding a Singleton interface to it.
You'd then be able to access it from anywhere:
[HelloWorldLayer sharedWorldLayer].touchingBodies;