View previous topic :: View next topic |
Author |
Message |
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Mon Jan 26, 2009 6:59 pm Post subject: Some help with linking in a C lib? |
|
|
After spending too much time trying to write my own crappy physics system for my game library, I decided to take a stab at integrating Chipmunk (http://wiki.slembcke.net/main/published/Chipmunk). Chipmunk is a C library, so I downloaded and built it as per instructions. I moved the libchipmunk.a and libchipmunk.so.4 files to ~/d/lib/, because DSSS automatically looks there for libraries.
Then I used bcdgen on the chipmunk.h (which specifies imports to all the other .h files) to create a D binding file. I cleaned it up a bit and saved it as chipmunk.d in a subdir in my library. I also added
Code: | version (build) {
pragma(link, "chipmunk"); // Tell DSSS to link against libchipmunk.a
} | just under the module declaration.
Then, in my physics.d, I import the chipmunk.d bindings and make use of the bound functions. I can then use DSSS to build and install my library. If, however, I attempt to build a binary which imports my library, I get linker errors. I can also reproduce these errors by adding a unittest in my physics.d (part of the library) and using dsss build -test.
Here's the funny thing: I'm using a number of structs and functions which are defined in the bindings, but only 1 of them seems to fail to link.
Here are the relevant bits:
chipmunk.d Code: | module ninja.chipmunk.chipmunk;
version (build) {
pragma(link, "chipmunk"); // Tell DSSS to link against libchipmunk.a
}
...
extern (C) {
void cpArrayDestroy(cpArray *);
void cpBodySetMass(cpBody *, double);
...
cpVect cpvrotate(cpVect, cpVect);
cpVect cpv(double, double);
void cpBodyApplyImpulse(cpBody *, cpVect, cpVect);
...
} |
physics.d Code: | public class PhysicsBody {
public cpBody BMember;
public cpShape[] Shapes;
public bool Static = false;
public Vector2 Position() { return new Vector2(BMember.p.x, BMember.p.y); }
public Vector2 Position(Vector2 value) { BMember.p.x = value.X; BMember.p.y = value.Y; return value;}
...
this(bool isStatic, ConvexHullGroup hullgroup, double mass) {
Static = isStatic;
Mass = mass;
if (isStatic)
BMember = *cpBodyNew(INFINITY, INFINITY);
else {
// Calculate mass, etc.
cpVect[] hull_points = new cpVect[](hullgroup[0].HullPoints.length);
foreach (int index, Vector2 hp; hullgroup[0].HullPoints)
hull_points[index] = cpv(hp.X, hp.Y);
double moment = cpMomentForPoly(mass, hull_points.length, hull_points.ptr, cpvzero);
BMember = *cpBodyNew(mass, moment);
}
// Create shapes
Shapes.length = hullgroup.Hulls.length;
foreach (int hullIndex, ConvexHull hull; hullgroup.Hulls)
{
if (hull.Type == 0)
{
cpVect[] verts = new cpVect[](hull.HullPoints.length);
foreach (int i, Vector2 hp; hull.HullPoints)
verts[i] = cpv(hp.X, hp.Y);
Shapes[hullIndex] = *cpPolyShapeNew(&BMember, verts.length, verts.ptr, cpvzero);
Shapes[hullIndex].e = Elascity;
Shapes[hullIndex].u = Friction;
}
}
}
}
unittest {
PhysicsBody pb = new PhysicsBody(true, new ConvexHullGroup("<P{0:0,0:100,100:100}>"), 1);
} |
And finally, the build output:
Code: | justin@magus:~/whear/ninja/src$ dsss build -test && dsss install
Creating imports for DD-ninja
ninja => DD-ninja
+ /opt/dsss-0.75-dmd-gnuWlinux-x86/bin/rebuild -Idsss_imports/ -I. -S./ -I/opt/dsss-0.75-dmd-gnuWlinux-x86/include/d -S/opt/dsss-0.75-dmd-gnuWlinux-x86/lib/ -I/opt/dsss-0.75-dmd-gnuWlinux-x86/include/d -S/opt/dsss-0.75-dmd-gnuWlinux-x86/lib -I/home/justin/d/include/d -S/home/justin/d/lib -oqdsss_objs/D -no-export-dynamic -explicit -lib ninja/misc.d ninja/collection.d ninja/markup.d ninja/engine.d ninja/font.d ninja/level.d ninja/window.d ninja/chipmunk/chipmunk.d ninja/physics.d ninja/effects/particle.d ninja/effects/attractors.d ninja/effects/particles.d ninja/effects/emitters.d ninja/quadtree.d ninja/tangible.d ninja/vector.d ninja/gui/ui.d ninja/light.d ninja/drawing.d -oflibDD-ninja.a -full
Testing DD-ninja
+ /opt/dsss-0.75-dmd-gnuWlinux-x86/bin/rebuild -Idsss_imports/ -I. -S./ -I/opt/dsss-0.75-dmd-gnuWlinux-x86/include/d -S/opt/dsss-0.75-dmd-gnuWlinux-x86/lib/ -I/opt/dsss-0.75-dmd-gnuWlinux-x86/include/d -S/opt/dsss-0.75-dmd-gnuWlinux-x86/lib -I/home/justin/d/include/d -S/home/justin/d/lib -oqdsss_objs/D -no-export-dynamic -unittest -full ninja/misc.d ninja/collection.d ninja/markup.d ninja/engine.d ninja/font.d ninja/level.d ninja/window.d ninja/chipmunk/chipmunk.d ninja/physics.d ninja/effects/particle.d ninja/effects/attractors.d ninja/effects/particles.d ninja/effects/emitters.d ninja/quadtree.d ninja/tangible.d ninja/vector.d ninja/gui/ui.d ninja/light.d ninja/drawing.d /opt/dsss-0.75-dmd-gnuWlinux-x86/share/dsss/dsss_lib_test.d -oftest_DD-ninja
dsss_objs/D/ninja.physics.o: In function `_D5ninja7physics11PhysicsBody5_ctorMFbC5ninja7physics15ConvexHullGroupdZC5ninja7physics11PhysicsBody':
ninja/physics.d:(.text._D5ninja7physics11PhysicsBody5_ctorMFbC5ninja7physics15ConvexHullGroupdZC5ninja7physics11PhysicsBody+0xeb): undefined reference to `cpv'
ninja/physics.d:(.text._D5ninja7physics11PhysicsBody5_ctorMFbC5ninja7physics15ConvexHullGroupdZC5ninja7physics11PhysicsBody+0x232): undefined reference to `cpv'
dsss_objs/D/ninja.physics.o: In function `_D5ninja7physics11WorldSystem7GravityMFC5ninja6vector7Vector2ZC5ninja6vector7Vector2':
ninja/physics.d:(.text._D5ninja7physics11WorldSystem7GravityMFC5ninja6vector7Vector2ZC5ninja6vector7Vector2+0x24): undefined reference to `cpv'
collect2: ld returned 1 exit status
--- errorlevel 1
Command /opt/dsss-0.75-dmd-gnuWlinux-x86/bin/rebuild returned with code 65280, aborting.
Error: Command failed, aborting. |
If I'm reading this correctly, the function cpv isn't found (and presumably the other functions which I use are?), despite it being clearly defined in chipmunk.d
Thanks for any help. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Mon Jan 26, 2009 7:25 pm Post subject: |
|
|
Will the fact that cpv is defined as an inline function in the C source have any dramatic implications for my code?
From cpVect.h:
Code: | typedef struct cpVect{
cpFloat x,y;
} cpVect;
static const cpVect cpvzero={0.0f,0.0f};
static inline cpVect
cpv(const cpFloat x, const cpFloat y)
{
cpVect v = {x, y};
return v;
} |
|
|
Back to top |
|
|
clayasaurus
Joined: 21 May 2004 Posts: 857
|
Posted: Mon Jan 26, 2009 8:15 pm Post subject: |
|
|
Hello,
Why not just use Blaze? It is based off of box2d.org just like Chipmunk, except it's written in D and object oriented.
http://www.dsource.org/projects/blaze
~ Clay |
|
Back to top |
|
|
doob
Joined: 06 Jan 2007 Posts: 367
|
Posted: Tue Jan 27, 2009 5:18 am Post subject: |
|
|
JNewt wrote: | Will the fact that cpv is defined as an inline function in the C source have any dramatic implications for my code? |
I think that that is just what the problem is, it's inlined. Copy the whole function into your D code and not just the declaration. |
|
Back to top |
|
|
JNewt
Joined: 05 Jun 2008 Posts: 69
|
Posted: Tue Jan 27, 2009 10:31 am Post subject: |
|
|
Yes, making it a simple D static function works. Thanks.
@clayasaurus:
I've looked at Blaze, and it looks as though it'd be much easier to integrate. Unfortunately, I'm not sure that it's quite stable enough for my purposes. I used dsss net install to get blaze-phobos-demos--they built, but the demo segfaulted shortly after starting. Given that the original author is currently inactive, I think I'd rather go with something that has a good history of working well and being very fast. If Blaze gets more solidity and polish, I may switch over to it sometime in the future. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|