This question already has answers here:
C++:Undefined reference to 'FMOD:: X'
(3 answers)
Closed 5 years ago.
I know this will probably a rather dumb question, but after two days of trying, i thought i would ask anyway. I’m quite new to C++, so I think there will be a very simple solution to this.
When I try to compile the examples in the low level examples section of the FMOD API on the command line I get always ‘undefined reference’ errors for the FMOD stuff. I know there must be a problem with the libraries, but as you can see in the makefile, I tried to include everything:
In the lib folder of the FMOD API are:
fmod_vc.lib , fmodL_vc.lib, fmod64_vc.lib, fmodL64_vc.lib, libfmod.a, libfmodL.a
I use the latest version of the FMOD API on Windows 8.1 64 bit. The problem is independent of the compiler. I tried GCC/Cygwin and CLANG. The error output is produced by MinGW. I think I searched pretty everywhere on the net. The anwsers to: C++:Undefined reference to 'FMOD:: X' are not working for me. As far as I can see, there is no more fmodex_vc.lib/fmodex64_vc.lib in the API.
Here is my makefile:
CFLAGS = -m64 -c -Wall -g --std=c++11
LFLAGS = -m64 -g -Wl,-rpath=../lib
INCLUDE_PATH = -I../inc
LIBRARY_PATH = -L../lib
LIBS = -lfmod64 -lfmodL64 -lfmod64_vc -lfmodL64_vc
all: generate_tone.o common.o common_platform.o
g++ $(LFLAGS) $(LIBRARY_PATH) generate_tone.o common.o common_platform.o -o generate.exe ../lib/libfmod.a ../lib/libfmodL.a $(LIBS)
common.o: common.cpp common.h
g++ $(CFLAGS) $(INCLUDE_PATH) common.cpp -o common.o
common_platform.o: common_platform.cpp common_platform.h
g++ $(CFLAGS) $(INCLUDE_PATH) common_platform.cpp -o common_platform.o
generate_tone.o: generate_tone.cpp
g++ $(CFLAGS) $(INCLUDE_PATH) generate_tone.cpp -o generate_tone.o
And here are the error messages:
generate_tone.o: In function `FMOD_Main()':
c:\cSandBox\fmod\examples/generate_tone.cpp:28: undefined reference to `FMOD::System::getVersion(unsigned int*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:36: undefined reference to `FMOD::System::init(int, unsigned int, void*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:42: undefined reference to `FMOD::System::createDSPByType(FMOD_DSP_TYPE, FMOD::DSP**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:44: undefined reference to `FMOD::DSP::setParameterFloat(int, float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:58: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:62: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:64: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:66: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:68: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:76: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:80: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:82: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:84: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:86: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:94: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:98: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:100: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:102: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:104: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:112: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:116: undefined reference to `FMOD::System::playDSP(FMOD::DSP*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
c:\cSandBox\fmod\examples/generate_tone.cpp:118: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:120: undefined reference to `FMOD::DSP::setParameterInt(int, int)'
c:\cSandBox\fmod\examples/generate_tone.cpp:122: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
c:\cSandBox\fmod\examples/generate_tone.cpp:130: undefined reference to `FMOD::ChannelControl::stop()'
c:\cSandBox\fmod\examples/generate_tone.cpp:142: undefined reference to `FMOD::ChannelControl::getVolume(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:149: undefined reference to `FMOD::ChannelControl::setVolume(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:157: undefined reference to `FMOD::Channel::getFrequency(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:162: undefined reference to `FMOD::Channel::setFrequency(float)'
c:\cSandBox\fmod\examples/generate_tone.cpp:167: undefined reference to `FMOD::System::update()'
c:\cSandBox\fmod\examples/generate_tone.cpp:176: undefined reference to `FMOD::Channel::getFrequency(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:178: undefined reference to `FMOD::ChannelControl::getVolume(float*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:180: undefined reference to `FMOD::ChannelControl::isPlaying(bool*)'
c:\cSandBox\fmod\examples/generate_tone.cpp:209: undefined reference to `FMOD::DSP::release()'
c:\cSandBox\fmod\examples/generate_tone.cpp:211: undefined reference to `FMOD::System::close()'
c:\cSandBox\fmod\examples/generate_tone.cpp:213: undefined reference to `FMOD::System::release()'
common_platform.o: In function `Common_Init(void**)':
c:\cSandBox\fmod\examples/common_platform.cpp:78: undefined reference to `__imp_CoInitializeEx'
common_platform.o: In function `Common_Close()':
c:\cSandBox\fmod\examples/common_platform.cpp:83: undefined reference to `__imp_CoUninitialize'
collect2.exe: error: ld returned 1 exit status
And here is the source file:
/*==============================================================================
Generate Tone Example
Copyright (c), Firelight Technologies Pty, Ltd 2004-2017.
This example shows how to play generated tones using System::playDSP
instead of manually connecting and disconnecting DSP units.
==============================================================================*/
#include "fmod.hpp"
#include "common.h"
int FMOD_Main()
{
FMOD::System *system;
FMOD::Channel *channel = 0;
FMOD::DSP *dsp;
FMOD_RESULT result;
unsigned int version;
void *extradriverdata = 0;
Common_Init(&extradriverdata);
/*
Create a System object and initialize.
*/
result = FMOD::System_Create(&system);
ERRCHECK(result);
result = system->getVersion(&version);
ERRCHECK(result);
if (version < FMOD_VERSION)
{
Common_Fatal("FMOD lib version %08x doesn't match header version %08x", version, FMOD_VERSION);
}
result = system->init(32, FMOD_INIT_NORMAL, extradriverdata);
ERRCHECK(result);
/*
Create an oscillator DSP units for the tone.
*/
result = system->createDSPByType(FMOD_DSP_TYPE_OSCILLATOR, &dsp);
ERRCHECK(result);
result = dsp->setParameterFloat(FMOD_DSP_OSCILLATOR_RATE, 440.0f); /* Musical note 'A' */
ERRCHECK(result);
/*
Main loop
*/
do
{
Common_Update();
if (Common_BtnPress(BTN_ACTION1))
{
if (channel)
{
result = channel->stop();
ERRCHECK(result);
}
result = system->playDSP(dsp, 0, true, &channel);
ERRCHECK(result);
result = channel->setVolume(0.5f);
ERRCHECK(result);
result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 0);
ERRCHECK(result);
result = channel->setPaused(false);
ERRCHECK(result);
}
if (Common_BtnPress(BTN_ACTION2))
{
if (channel)
{
result = channel->stop();
ERRCHECK(result);
}
result = system->playDSP(dsp, 0, true, &channel);
ERRCHECK(result);
result = channel->setVolume(0.125f);
ERRCHECK(result);
result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 1);
ERRCHECK(result);
result = channel->setPaused(false);
ERRCHECK(result);
}
if (Common_BtnPress(BTN_ACTION3))
{
if (channel)
{
result = channel->stop();
ERRCHECK(result);
}
result = system->playDSP(dsp, 0, true, &channel);
ERRCHECK(result);
result = channel->setVolume(0.125f);
ERRCHECK(result);
result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 2);
ERRCHECK(result);
result = channel->setPaused(false);
ERRCHECK(result);
}
if (Common_BtnPress(BTN_ACTION4))
{
if (channel)
{
result = channel->stop();
ERRCHECK(result);
}
result = system->playDSP(dsp, 0, true, &channel);
ERRCHECK(result);
result = channel->setVolume(0.5f);
ERRCHECK(result);
result = dsp->setParameterInt(FMOD_DSP_OSCILLATOR_TYPE, 4);
ERRCHECK(result);
result = channel->setPaused(false);
ERRCHECK(result);
}
if (Common_BtnPress(BTN_MORE))
{
if (channel)
{
result = channel->stop();
ERRCHECK(result);
channel = 0;
}
}
if (channel)
{
if (Common_BtnDown(BTN_UP) || Common_BtnDown(BTN_DOWN))
{
float volume;
result = channel->getVolume(&volume);
ERRCHECK(result);
volume += (Common_BtnDown(BTN_UP) ? +0.1f : -0.1f);
volume = (volume > 1.0f) ? 1.0f : volume;
volume = (volume < 0.0f) ? 0.0f : volume;
result = channel->setVolume(volume);
ERRCHECK(result);
}
if (Common_BtnDown(BTN_LEFT) || Common_BtnDown(BTN_RIGHT))
{
float frequency;
result = channel->getFrequency(&frequency);
ERRCHECK(result);
frequency += (Common_BtnDown(BTN_RIGHT) ? +500.0f : -500.0f);
result = channel->setFrequency(frequency);
ERRCHECK(result);
}
}
result = system->update();
ERRCHECK(result);
{
float frequency = 0.0f, volume = 0.0f;
bool playing = false;
if (channel)
{
result = channel->getFrequency(&frequency);
ERRCHECK(result);
result = channel->getVolume(&volume);
ERRCHECK(result);
result = channel->isPlaying(&playing);
ERRCHECK(result);
}
Common_Draw("==================================================");
Common_Draw("Generate Tone Example.");
Common_Draw("Copyright (c) Firelight Technologies 2004-2017.");
Common_Draw("==================================================");
Common_Draw("");
Common_Draw("Press %s to play a sine wave", Common_BtnStr(BTN_ACTION1));
Common_Draw("Press %s to play a square wave", Common_BtnStr(BTN_ACTION2));
Common_Draw("Press %s to play a saw wave", Common_BtnStr(BTN_ACTION3));
Common_Draw("Press %s to play a triangle wave", Common_BtnStr(BTN_ACTION4));
Common_Draw("Press %s to stop the channel", Common_BtnStr(BTN_MORE));
Common_Draw("Press %s and %s to change volume", Common_BtnStr(BTN_UP), Common_BtnStr(BTN_DOWN));
Common_Draw("Press %s and %s to change frequency", Common_BtnStr(BTN_LEFT), Common_BtnStr(BTN_RIGHT));
Common_Draw("Press %s to quit", Common_BtnStr(BTN_QUIT));
Common_Draw("");
Common_Draw("Channel is %s", playing ? "playing" : "stopped");
Common_Draw("Volume %0.2f", volume);
Common_Draw("Frequency %0.2f", frequency);
}
Common_Sleep(50);
} while (!Common_BtnPress(BTN_QUIT));
/*
Shut down
*/
result = dsp->release();
ERRCHECK(result);
result = system->close();
ERRCHECK(result);
result = system->release();
ERRCHECK(result);
Common_Close();
return 0;
}
The compiling works great, did I miss a library?
In fact the solution was on C++:Undefined reference to 'FMOD:: X' but I didn't see it. I try to make it clear here for anybody, who stumbles on the same problem.
"Because the name-mangling systems for such features are not standardized across compilers, few linkers can link object code that was produced by different compilers."
https://en.wikipedia.org/wiki/Name_mangling#How_different_compilers_mangle_the_same_functions
So none of the compilers I used could cope with the Visual Studio compiled libraries.
Related
I'm currently debugging a C/C++ program I wrote that uses Bullet Physics. I'm working on Ubuntu 14.04.3, using g++ 4.8.4, valgrind 3.10.1, and Bullet Physics 2.82.
My compiling command (for debugging) is:
g++ -fno-inline -O0 -g -Wall -Wl,-rpath=./more_libs/lib,--enable-new-dtags -std=gnu++11 -I../bullet-2.82-r2704/Demos/OpenGL/ -I./more_libs/include/ -I../bullet-2.82-r2704/src/ ./main.cpp -L../bullet-2.82-r2704/Glut/ -L./more_libs/lib/ -L./more_libs/mesa -L../bullet-build/Demos/OpenGL/ -L../more_libs/lib/x86_64-linux-gnu -L../bullet-build/src/BulletDynamics/ -L../bullet-build/src/BulletCollision/ -L../bullet-build/src/LinearMath/ -lOpenGLSupport -lGL -lGLU -lglut -lBulletDynamics -lBulletCollision -lLinearMath -lXi -lXxf86vm -lX11 -o ./app
(The difference between debugging and normal is the -O0 and -fno-inline options. I'm adding library paths because I need this program to be portable to a cluster I don't have super-user privileges on.)
Using Valgrind, I have found a ton of similar Uninitialized Value errors that look like this:
Conditional jump or move depends on uninitialised value(s)
at 0x4608C1: btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x4591FC: btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject**, int, btPersistentManifold**, int, btTypedConstraint**, int, btContactSolverInfo const&, btIDebugDraw*, btDispatcher*) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x46A3FF: btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo&) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x467584: btDiscreteDynamicsWorld::internalSingleStepSimulation(float) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x465459: btDiscreteDynamicsWorld::stepSimulation(float, int, float) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x4088F4: NoiseWorld::clientMoveAndDisplay() (NoiseWorld.cpp:288)
by 0x409A28: main (main.cpp:46)
Uninitialised value was created by a heap allocation
at 0x4C2ABBD: malloc (vg_replace_malloc.c:296)
by 0x4EE043: btAlignedAllocDefault(unsigned long, int) (in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)
by 0x40BC09: btHingeConstraint::operator new(unsigned long) (btHingeConstraint.h:103)
by 0x40CF73: NoiseWorld::CreateHinge(int, int, int, float, float, float, float, float, float, float, float, bool) (NoiseWorld.h:332)
by 0x40807C: NoiseWorld::initPhysics() (NoiseWorld.cpp:193)
by 0x4099F4: main (main.cpp:41)
I've tried to look what's going on at solveGroupCacheFriendlySetup(), but when I set a breakpoint there and run GDB, the program doesn't stop---it just runs to completion. I've set the breakpoint by function and by memory (which is constant across valgrind checks), but none of them are getting found/used.
So, here's the question: How can I look at what's going on in solveGroupCacheFriendlySetup() during the run of program? From there, I think I'll be able to figure out what was left uninitialized.
Sorry in advance if this is a simple question, but I haven't been able to find the answer for the past two days. I'm a novice programmer and I've taken on a big project, so I'm guessing there's something simple I'm doing wrong, but I don't know exactly to what ask at this point.
EDIT:
Here is the function I need to look at while running, as per πάντα ῥεῖ's suggestion. The online documentation for this function can be found here: http://bulletphysics.org/Bullet/BulletFull/classbtSequentialImpulseConstraintSolver.html
Note: This portion of the code was not written by me, and I'm not 100% what it does. I'm pretty sure the error lies elsewhere; that I'm not setting up the physics-simulator environment well enough.
Also, I do not know what the valgrind message "(in /home/josh/Documents/projects/evodevo_model/noise/EvoDevo-Modeling/evodevo/c++/app)" means in terms of trying to add a breakpoint that GDB can find when running the program.
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
{
m_fixedBodyId = -1;
BT_PROFILE("solveGroupCacheFriendlySetup");
(void)debugDrawer;
m_maxOverrideNumSolverIterations = 0;
#ifdef BT_ADDITIONAL_DEBUG
//make sure that dynamic bodies exist for all (enabled) constraints
for (int i=0;i<numConstraints;i++)
{
btTypedConstraint* constraint = constraints[i];
if (constraint->isEnabled())
{
if (!constraint->getRigidBodyA().isStaticOrKinematicObject())
{
bool found=false;
for (int b=0;b<numBodies;b++)
{
if (&constraint->getRigidBodyA()==bodies[b])
{
found = true;
break;
}
}
btAssert(found);
}
if (!constraint->getRigidBodyB().isStaticOrKinematicObject())
{
bool found=false;
for (int b=0;b<numBodies;b++)
{
if (&constraint->getRigidBodyB()==bodies[b])
{
found = true;
break;
}
}
btAssert(found);
}
}
}
//make sure that dynamic bodies exist for all contact manifolds
for (int i=0;i<numManifolds;i++)
{
if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
{
bool found=false;
for (int b=0;b<numBodies;b++)
{
if (manifoldPtr[i]->getBody0()==bodies[b])
{
found = true;
break;
}
}
btAssert(found);
}
if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
{
bool found=false;
for (int b=0;b<numBodies;b++)
{
if (manifoldPtr[i]->getBody1()==bodies[b])
{
found = true;
break;
}
}
btAssert(found);
}
}
#endif //BT_ADDITIONAL_DEBUG
for (int i = 0; i < numBodies; i++)
{
bodies[i]->setCompanionId(-1);
}
m_tmpSolverBodyPool.reserve(numBodies+1);
m_tmpSolverBodyPool.resize(0);
//btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
//initSolverBody(&fixedBody,0);
//convert all bodies
for (int i=0;i<numBodies;i++)
{
int bodyId = getOrInitSolverBody(*bodies[i],infoGlobal.m_timeStep);
btRigidBody* body = btRigidBody::upcast(bodies[i]);
if (body && body->getInvMass())
{
btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
btVector3 gyroForce (0,0,0);
if (body->getFlags()&BT_ENABLE_GYROPSCOPIC_FORCE)
{
gyroForce = body->computeGyroscopicForce(infoGlobal.m_maxGyroscopicForce);
solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep;
}
}
}
if (1)
{
int j;
for (j=0;j<numConstraints;j++)
{
btTypedConstraint* constraint = constraints[j];
constraint->buildJacobian();
constraint->internalSetAppliedImpulse(0.0f);
}
}
//btRigidBody* rb0=0,*rb1=0;
//if (1)
{
{
int totalNumRows = 0;
int i;
m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
//calculate the total number of contraint rows
for (i=0;i<numConstraints;i++)
{
btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
btJointFeedback* fb = constraints[i]->getJointFeedback();
if (fb)
{
fb->m_appliedForceBodyA.setZero();
fb->m_appliedTorqueBodyA.setZero();
fb->m_appliedForceBodyB.setZero();
fb->m_appliedTorqueBodyB.setZero();
}
if (constraints[i]->isEnabled())
{
}
if (constraints[i]->isEnabled())
{
constraints[i]->getInfo1(&info1);
} else
{
info1.m_numConstraintRows = 0;
info1.nub = 0;
}
totalNumRows += info1.m_numConstraintRows;
}
m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
///setup the btSolverConstraints
int currentRow = 0;
for (i=0;i<numConstraints;i++)
{
const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
if (info1.m_numConstraintRows)
{
btAssert(currentRow<totalNumRows);
btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
btTypedConstraint* constraint = constraints[i];
btRigidBody& rbA = constraint->getRigidBodyA();
btRigidBody& rbB = constraint->getRigidBodyB();
int solverBodyIdA = getOrInitSolverBody(rbA,infoGlobal.m_timeStep);
int solverBodyIdB = getOrInitSolverBody(rbB,infoGlobal.m_timeStep);
btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;
if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)
m_maxOverrideNumSolverIterations = overrideNumSolverIterations;
int j;
for ( j=0;j<info1.m_numConstraintRows;j++)
{
memset(¤tConstraintRow[j],0,sizeof(btSolverConstraint));
currentConstraintRow[j].m_lowerLimit = -SIMD_INFINITY;
currentConstraintRow[j].m_upperLimit = SIMD_INFINITY;
currentConstraintRow[j].m_appliedImpulse = 0.f;
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations;
}
bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
btTypedConstraint::btConstraintInfo2 info2;
info2.fps = 1.f/infoGlobal.m_timeStep;
info2.erp = infoGlobal.m_erp;
info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1;
info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2;
info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
///the size of btSolverConstraint needs be a multiple of btScalar
btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
info2.m_constraintError = ¤tConstraintRow->m_rhs;
currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
info2.m_damping = infoGlobal.m_damping;
info2.cfm = ¤tConstraintRow->m_cfm;
info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit;
info2.m_upperLimit = ¤tConstraintRow->m_upperLimit;
info2.m_numIterations = infoGlobal.m_numIterations;
constraints[i]->getInfo2(&info2);
///finalize the constraint setup
for ( j=0;j<info1.m_numConstraintRows;j++)
{
btSolverConstraint& solverConstraint = currentConstraintRow[j];
if (solverConstraint.m_upperLimit>=constraints[i]->getBreakingImpulseThreshold())
{
solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold();
}
if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold())
{
solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold();
}
solverConstraint.m_originalContactPoint = constraint;
{
const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
}
{
const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
}
{
btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass();
btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal?
btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1);
sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
sum += iMJlB.dot(solverConstraint.m_contactNormal2);
sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
btScalar fsum = btFabs(sum);
btAssert(fsum > SIMD_EPSILON);
solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f;
}
{
btScalar rel_vel;
btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0,0,0);
btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0,0,0);
btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0,0,0);
btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ?bodyBPtr->m_externalTorqueImpulse : btVector3(0,0,0);
btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()+externalForceImpulseA)
+ solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()+externalTorqueImpulseA);
btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()+externalForceImpulseB)
+ solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()+externalTorqueImpulseB);
rel_vel = vel1Dotn+vel2Dotn;
btScalar restitution = 0.f;
btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
btScalar velocityError = restitution - rel_vel * info2.m_damping;
btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
solverConstraint.m_appliedImpulse = 0.f;
}
}
}
currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows;
}
}
convertContacts(manifoldPtr,numManifolds,infoGlobal);
}
// btContactSolverInfo info = infoGlobal;
int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
int numConstraintPool = m_tmpSolverContactConstraintPool.size();
int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
///#todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool);
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool*2);
else
m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool);
m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool);
{
int i;
for (i=0;i<numNonContactPool;i++)
{
m_orderNonContactConstraintPool[i] = i;
}
for (i=0;i<numConstraintPool;i++)
{
m_orderTmpConstraintPool[i] = i;
}
for (i=0;i<numFrictionPool;i++)
{
m_orderFrictionConstraintPool[i] = i;
}
}
return 0.f;
}
If you want to debug your program when running it under valgrind,
then you can do the following:
valgrind --vgdb-error=1 .... rest of the args as usual
Then on first error, valgrind will stop, and will wait for gdb to connect.
You can then use gdb commands and/or valgrind specific features to
investigate the problem. You can continue execution using the gdb continue
command, to stop on the next error.
See http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver for more information.
I've writing a "big" Indexs project in C++, that is difficult for me meanwhile...
While i was trying to create an inheritance between 2 clases:
ZonalPermutant wich inherit from Permutant
i got the following error:
error:
g++ -Wall -std=c++0x lib/PermZone.o lib/VectorSpace.o lib/Vector.o lib/PermZoneMain.o lib/Permutant.o lib/ZonalPermutant.o -o permZone
lib/Permutant.o: In function `Permutant::Permutant()':
Permutant.cpp:(.text+0x20): undefined reference to `vtable for Permutant'
lib/Permutant.o: In function `Permutant::Permutant(long)':
Permutant.cpp:(.text+0x8e): undefined reference to `vtable for Permutant'
lib/Permutant.o: In function `Permutant::Permutant(PList<long>*, long)':
Permutant.cpp:(.text+0x10c): undefined reference to `vtable for Permutant'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant()':
ZonalPermutant.cpp:(.text+0x41): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant(long)':
ZonalPermutant.cpp:(.text+0xa4): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::ZonalPermutant(PList<long>*, PList<long>*, long)':
ZonalPermutant.cpp:(.text+0x13e): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o: In function `ZonalPermutant::~ZonalPermutant()':
ZonalPermutant.cpp:(.text._ZN14ZonalPermutantD2Ev[_ZN14ZonalPermutantD5Ev]+0x2f): undefined reference to `Permutant::~Permutant()'
lib/ZonalPermutant.o:(.rodata._ZTI14ZonalPermutant[_ZTI14ZonalPermutant]+0x10): undefined reference to `typeinfo for Permutant'
collect2: error: ld returned 1 exit status
Makefile:17: recipe for target 'permZone' failed
make: *** [permZone] Error 1
I know it is probably that the linking in my makefile could be wrong written. So i will show you my makefile:
makefile:
CC = g++
STD = -std=c++0x
DIR = -I .
CFLAGS = -Wall -c $(STD)
LFLAGS = -Wall $(STD)
BRUTEFORCE_LIB = lib/VectorSpace.o lib/Vector.o lib/BruteForce.o lib/BruteForceMain.o
PIVOT_LIB = lib/VectorSpace.o lib/Vector.o lib/Pivot.o lib/PivotMain.o
PERM_LIB = lib/Permutants.o lib/VectorSpace.o lib/Vector.o lib/PermMain.o lib/Permutant.o
BASICS_LIB = lib/MajorOrderHeap.o lib/MinorOrderHeap.o lib/PList.o lib/OList.o lib/PList.o lib/HeapElement.o lib/Random.o lib/Tokenizer.o lib/Matrix.o
PERMZONE_LIB = lib/PermZone.o lib/VectorSpace.o lib/Vector.o lib/PermZoneMain.o lib/Permutant.o lib/ZonalPermutant.o
default: permZone
#EXE's
#PermZone
permZone: $(PERMZONE_LIB)
$(CC) $(LFLAGS) $(PERMZONE_LIB) -o permZone
lib/PermZoneMain.o: src/PermZoneMain.cpp src/Index.h src/Space.h
$(CC) src/PermZoneMain.cpp $(CFLAGS) -o lib/PermZoneMain.o
lib/PermZone.o: src/Indexes/PermZone/PermZone.h src/Indexes/PermZone/PermZone.cpp $(BASICS_LIB)
$(CC) src/Indexes/PermZone/PermZone.cpp $(CFLAGS) -o lib/PermZone.o
lib/ZonalPermutant.o: src/Indexes/PermZone/ZonalPermutant.cpp src/Indexes/PermZone/ZonalPermutant.h lib/Permutant.o
$(CC) src/Indexes/PermZone/ZonalPermutant.cpp $(CFLAGS) -o lib/ZonalPermutant.o
lib/Permutant.o: src/Element.h src/Indexes/Permutants/Permutant.h src/Indexes/Permutants/Permutant.cpp $(BASICS_LIB)
$(CC) src/Indexes/Permutants/Permutant.cpp $(CFLAGS) -o lib/Permutant.o
and now the h and cpp files (i know its a lot of text):
Permutant.h:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "../../Element.h"
#include "../../Basics/PList.h"
#ifndef PERMUTANT_H
#define PERMUTANT_H
class Permutant : public Element
{
protected:
PList<long> permutation;//stores only ID's
public:
bool isInverted;
Permutant();
~Permutant();
Permutant(long id);
Permutant(PList<long>* permutation,long id);
void setPermutation(PList<long>* permutation);
PList<long> getPermutation();
void invertPermutation();
long distance(Permutant* other);
string toString();
static long spearmanFootRule(Permutant &p1, Permutant &p2);
};
#endif // PERMUTANT_H
Permutant.cpp:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "Permutant.h"
//I dont like this trick.. but i have to use it for future distance calculations
typedef long (*P_distance)(Permutant&,Permutant&);//i hope it doesn't cause problems with inheritance :D
P_distance p_distance;
Permutant::Permutant()
{
isInverted = false;
p_distance = &spearmanFootRule;
}
Permutant::Permutant(long id)
{
this->id = id;
isInverted = false;
p_distance = &spearmanFootRule;
}
Permutant::Permutant(PList<long>* permutation,long id)
{
this->id = id;
isInverted = false;
this->permutation = *permutation;
p_distance = &spearmanFootRule;
}
void Permutant::setPermutation(PList<long>* permutation)
{
this->permutation = *permutation;
}
PList<long> Permutant::getPermutation()
{
return this->permutation;
}
void Permutant::invertPermutation()
{
PList<long> *inverted_permutation = new PList<long>(permutation.size());
inverted_permutation->toArray();
for (long i = 0; i < permutation.size(); ++i)
{
(*inverted_permutation)[permutation[i]] = i;
}
this->setPermutation(inverted_permutation);
this->isInverted = !isInverted;
}
long Permutant::distance(Permutant* other)
{
return p_distance(*this, *other);
}
string Permutant::toString()
{
ostringstream oss;
oss << ((isInverted)?"i":"")<< " " << permutation.toString();
return oss.str();
}
long Permutant::spearmanFootRule(Permutant &p1, Permutant &p2)
{
long dist = 0;
if(p1.isInverted == p2.isInverted)
{
p1.invertPermutation();
}
for (int i = 0; i < p2.getPermutation().size(); ++i)
{
dist+= abs(p1.getPermutation().get(p2.getPermutation().get(i)) - i);
}
return dist;
}
ZonalPermutant:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "../Permutants/Permutant.h"
#ifndef ZONAL_PERMUTANT_H
#define ZONAL_PERMUTANT_H
class ZonalPermutant :public Permutant
{
private:
PList<long> zones;
public:
ZonalPermutant();
~ZonalPermutant(){};
ZonalPermutant(long id);
ZonalPermutant(PList<long>* permutation, PList<long>* zones, long id);
void setZones(PList<long>* zones);
PList<long> getZones();
long distance(Permutant* other);
string toString();
};
#endif // ZONAL_PERMUTANT_H
ZonalPermutant.cpp:
//
// Created by Maximiliano Verdugo on 28/12/15.
// Copyright © 2016 Maximiliano Verdugo. All rights reserved.
//
#include "ZonalPermutant.h"
ZonalPermutant::ZonalPermutant() : Permutant()
{}
ZonalPermutant::ZonalPermutant(long id) : Permutant(id)
{}
ZonalPermutant::ZonalPermutant(PList<long>* permutation, PList<long>* zones, long id) : Permutant(permutation,id)
{
this->zones = *zones;
}
void ZonalPermutant::setZones(PList<long>* zones)
{
this->zones = *zones;
}
PList<long> ZonalPermutant::getZones()
{
return this->zones;
}
long ZonalPermutant::distance(Permutant* other)
{
return 0;
}
string ZonalPermutant::toString()
{
return ":D";
}
Every of the other classes used in my code are good implemented and they dont create any problem at the moment of compiling and linking others Indexes...
If there is any problem in my code or way to programm, i would like that you say that to me :).
Thanks you for the help.
Try declaring your destructors virtual (usually no harm done if not necessary), and/or add their implementations to .cpp files. In my experience
Undefined reference to `vtable for Permutant'
hints to this direction.
I'm having a hard time trying to get an app to compile in Visual Studio 2013. I've solved a good amount of errors but I can't find a solution for the last one.
here it is:
void Application::setupRenderSystem() {
mState->dumpValues();
String val = mState->getStringValue("renderSystem");
RenderSystemList *renderSystems = mRoot->getAvailableRenderers();
RenderSystemList::iterator r_it;
bool renderSystemFound = false;
for (r_it = renderSystems->begin(); r_it != renderSystems->end(); r_it++) {
RenderSystem *tmp = *r_it;
std::string rName(tmp->getName());
// returns -1 if string not found
if ((int)rName.find(val) >= 0) {
mRoot->setRenderSystem(*r_it);
renderSystemFound = true;
break;
}
}
if (!renderSystemFound) {
OGRE_EXCEPT(0, "Specified render system (" + val + ") not found, exiting...", "Application")
}
}
Visual Studio indicates that the line RenderSystemList *renderSystems = mRoot->getAvailableRenderers(); is the problem, especially mRoot
Here is the error I get:
error C2440: 'initializing' : cannot convert from 'const Ogre::RenderSystemList' to 'Ogre::RenderSystemList *'
The getAvailableRenderers method doesn't return a pointer to a RenderSystemList. You'd want to have the value stored in a reference to a RenderSystemList:
RenderSystemList const& renderSystems = mRoot->getAvailableRenderers();
The Ogre API says:
const RenderSystemList & getAvailableRenderers (void)
So it returns a const reference and not a pointer.
Modify your code like this
const RenderSystemList &renderSystems = mRoot->getAvailableRenderers();
I've been trying to write an extension for Chrome that uses an NPAPI plugin. I'm using mingw to compile it. I struggled originally to get Chrome to load the plugin, but now I have a different problem.
I've managed to get Chrome to call NP_GetEntryPoints and NP_Initialize, but it crashes right after that. Here's my code so far...
main.cpp :
#include <iostream>
#include <cstdlib>
#include <Windows.h>
#include <npapi.h>
#include <npfunctions.h>
#define Exported extern "C" __declspec(dllexport)
NPNetscapeFuncs NPNFuncs;
Exported NPError NP_Initialize(NPNetscapeFuncs* pFuncs) {
if (pFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if (HIBYTE(pFuncs->version) > NP_VERSION_MAJOR)
return NPERR_INCOMPATIBLE_VERSION_ERROR;
if (pFuncs->size < sizeof(NPNetscapeFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
// Save functions
NPNFuncs.size = pFuncs->size;
NPNFuncs.version = pFuncs->version;
NPNFuncs.geturlnotify = pFuncs->geturlnotify;
NPNFuncs.geturl = pFuncs->geturl;
NPNFuncs.posturlnotify = pFuncs->posturlnotify;
NPNFuncs.posturl = pFuncs->posturl;
NPNFuncs.requestread = pFuncs->requestread;
NPNFuncs.newstream = pFuncs->newstream;
NPNFuncs.write = pFuncs->write;
NPNFuncs.destroystream = pFuncs->destroystream;
NPNFuncs.status = pFuncs->status;
NPNFuncs.uagent = pFuncs->uagent;
NPNFuncs.memalloc = pFuncs->memalloc;
NPNFuncs.memfree = pFuncs->memfree;
NPNFuncs.memflush = pFuncs->memflush;
NPNFuncs.reloadplugins = pFuncs->reloadplugins;
NPNFuncs.getJavaEnv = pFuncs->getJavaEnv;
NPNFuncs.getJavaPeer = pFuncs->getJavaPeer;
NPNFuncs.getvalue = pFuncs->getvalue;
NPNFuncs.setvalue = pFuncs->setvalue;
NPNFuncs.invalidaterect = pFuncs->invalidaterect;
NPNFuncs.invalidateregion = pFuncs->invalidateregion;
NPNFuncs.forceredraw = pFuncs->forceredraw;*/
// Success
MessageBoxA(0, "NP_Initialize", "Log", 0);
return NPERR_NO_ERROR;
}
Exported void NP_Shutdown() {
MessageBoxA(0, "NP_Shutdown", "Log", 0);
}
/* Entry points */
NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* savedData) {
MessageBoxA(0, "NPP_New", "Log", 0);
return NPERR_NO_ERROR;
}
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
MessageBoxA(0, "NPP_GetValue", "Log", 0);
return NPERR_NO_ERROR;
}
/*** Omitted... All the other functions are here, with just a MessageBox call in them ***/
Exported NPError NP_GetEntryPoints(NPPluginFuncs* pFuncs) {
if (pFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
if (pFuncs->size < sizeof(NPPluginFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
pFuncs->size = sizeof(NPPluginFuncs);
pFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
pFuncs->newp = &NPP_New;
pFuncs->destroy = &NPP_Destroy;
pFuncs->setwindow = &NPP_SetWindow;
pFuncs->newstream = &NPP_NewStream;
pFuncs->destroystream = &NPP_DestroyStream;
pFuncs->asfile = &NPP_StreamAsFile;
pFuncs->writeready = &NPP_WriteReady;
pFuncs->write = &NPP_Write;
pFuncs->print = &NPP_Print;
pFuncs->event = &NPP_HandleEvent;
pFuncs->urlnotify = &NPP_URLNotify;
pFuncs->getvalue = &NPP_GetValue;
pFuncs->setvalue = &NPP_SetValue;
pFuncs->javaClass = NULL;
pFuncs->gotfocus = &NPP_GotFocus;
pFuncs->lostfocus = &NPP_LostFocus;
pFuncs->urlredirectnotify = &NPP_URLRedirectNotify;
pFuncs->clearsitedata = &NPP_ClearSiteData;
pFuncs->getsiteswithdata = &NPP_GetSitesWithData;
MessageBoxA(0, "NP_GetEntryPoints", "Log", 0);
return NPERR_NO_ERROR;
}
I added a MessageBox call to every function, so I can see if the right functions are being called. When I run my test page, which is a blank page with an <embed> tag in it, I get a message saying NP_GetEntryPoints, then one saying NP_Initialize, then Chrome pops up a bar saying that my plugin has crashed. I think the problem is in my NP_GetEntryPoints, but I just can't see it... Is there anything I'm doing wrong, or forgetting to do?
I compile with :
g++.exe -DWIN32 -D_WIN32 -D_WINDOWS -D_WIN32_WINNT=0x0600 -D_WIN32_IE=0x0600 -D_UNICODE -DUNICODE -static-libgcc -static-libstdc++ -c "main.cpp" -o main.o
and
windres.exe "resource.rc" "resource.o"
and I link into a .DLL with :
g++.exe -Wl,--subsystem,windows -o "npplugin.dll" -s -shared main.o resource.o -lcomctl32 -lws2_32 -luxtheme -lgdi32 -lshell32 -lshlwapi
The size between function tables differs between browsers and version of browsers.
You check the size against your hard compiled library headers:
if (pFuncs->size < sizeof(NPNetscapeFuncs))
return NPERR_INVALID_FUNCTABLE_ERROR;
This can be the problem.
For example the latest (at the moment of writing gecko xulrunner SDK contains a 84 byte size struct:
typedef struct _NPPluginFuncs {
uint16_t size;
uint16_t version;
NPP_NewProcPtr newp;
NPP_DestroyProcPtr destroy;
NPP_SetWindowProcPtr setwindow;
NPP_NewStreamProcPtr newstream;
NPP_DestroyStreamProcPtr destroystream;
NPP_StreamAsFileProcPtr asfile;
NPP_WriteReadyProcPtr writeready;
NPP_WriteProcPtr write;
NPP_PrintProcPtr print;
NPP_HandleEventProcPtr event;
NPP_URLNotifyProcPtr urlnotify;
void* javaClass;
NPP_GetValueProcPtr getvalue;
NPP_SetValueProcPtr setvalue;
NPP_GotFocusPtr gotfocus;
NPP_LostFocusPtr lostfocus;
NPP_URLRedirectNotifyPtr urlredirectnotify;
NPP_ClearSiteDataPtr clearsitedata;
NPP_GetSitesWithDataPtr getsiteswithdata;
NPP_DidCompositePtr didComposite;
} NPPluginFuncs;
Chrome sends in a 80 byte struct.
So I guess the last function pointer is not in the struct used by chrome.
I would recommend using some form of logging rather than messageboxes; have you tried removing the messageboxes that are getting hit and see if you make it further? Chrome starts the plugin out of process, so it's going to expect those entrypoints to finish in a timely manner or else it'll likely kill the plugin.
Also, the --plugin-startup-dialog option may be useful to in in some cases just so you can see for sure when the plugin is starting; also, it may be useful if you wanted to attach a debugger and see if you can find more info that way. Just an FYI. I'd also try loading it in firefox; sometimes loading a plugin in another browser gives you different information. If it works in one and not the other, that can tell you something as well.
mm try to change in NP_GetEntryPoints()
pFuncs->newp = &NPP_New;
pFuncs->destroy = &NPP_Destroy;
(...)
to
pFuncs->newp = NPP_New;
pFuncs->destroy = NPP_Destroy;
When I try compiling this:
#include "OriAudioCache.hpp"
int main()
{
System *audioSystem(0);
FMOD_RESULT result;
result = System_Create(&audioSystem);
FMOD_CHECK_STATE(result);
OriAudioCache cache(audioSystem, 20);
string title("Ambitious Girl");
string path("/home/findrzkeeprz/Desktop/Resources/The_Ambitious_Girl.mp3");
cache.LoadSound(title, path, Default);
vector<OriSound>::iterator v_iter(cache.FindSound(title));
cache.PlaySound(v_iter->sound());
}
Which uses these files:
OriAudioCache.hpp
#ifndef ORI_AUDIO_CACHE_HPP_
#define ORI_AUDIO_CACHE_HPP_
#include "OriSound.hpp"
#include "OriChannel.hpp"
class OriAudioCache
{
public:
OriAudioCache(System *audioSystem, int maxChannels);
~OriAudioCache()
{
vector<OriSound>::iterator v_iter(audioCache_.begin());
for(; v_iter != audioCache_.end(); ++v_iter)
{
v_iter->~OriSound();
}
delete audioSystem_;
}
void LoadSound(string const& title, string const& path, AudioLoadMode mode);
vector<OriSound>::iterator FindSound(string const& title);
void RemoveSound(string const& title);
void PlaySound(Sound* sound);
vector<OriChannel>::iterator RequestChannel(bool &allocStatus, FMOD_CHANNELINDEX &allocMode);
void ReleaseChannel(Channel *channel);
private:
void inline SortChannels() {sort(channels_.begin(),channels_.end());}
vector<OriSound> audioCache_;
vector<OriChannel> channels_;
System *audioSystem_;
};
#endif
and OriAudioCache.cpp
#include "OriAudioCache.hpp"
OriAudioCache::OriAudioCache(System *audioSystem, int maxChannels)
:audioSystem_(audioSystem), channels_(maxChannels){}
void OriAudioCache::LoadSound(string const& title, string const& path, AudioLoadMode mode)
{
OriSound sound(title, path, audioSystem_, mode);
vector<OriSound>::iterator pos =lower_bound(audioCache_.begin(), audioCache_.end(), sound);
audioCache_.insert(pos, sound);
}
vector<OriSound>::iterator OriAudioCache::FindSound(string const& title)
{
vector<OriSound>::iterator v_iter(audioCache_.begin());
for(; v_iter != audioCache_.end(); ++v_iter) //Would better if I could use a binary search here
{
if(v_iter->title() == title) return v_iter;
else continue;
}
return audioCache_.end();
}
void OriAudioCache::RemoveSound(string const& title)
{
vector<OriSound>::iterator v_iter(audioCache_.begin());
for(; v_iter != audioCache_.end(); ++v_iter) //Would better if I could use a binary search here
{
if(v_iter->title() == title) audioCache_.erase(v_iter);
else continue;
}
}
void OriAudioCache::PlaySound(Sound* sound)
{
bool channelAlloc(false);
FMOD_CHANNELINDEX allocMode = FMOD_CHANNEL_FREE;
vector<OriChannel>::iterator oriChannel = RequestChannel(channelAlloc, allocMode);
if(channelAlloc)
{
FMOD_RESULT result;
Channel *chnl = oriChannel->channel();
result = audioSystem_->playSound(allocMode, sound, false, &chnl);
FMOD_CHECK_STATE(result);
bool isPlaying(false);
chnl->isPlaying(&isPlaying);
while(isPlaying)
{
chnl->isPlaying(&isPlaying);
}
bool paused(false);
chnl->getPaused(&paused);
if(!paused)
{
ReleaseChannel(chnl);
}
SortChannels(); //sort channels, reoder for channel requests
}
}
vector<OriChannel>::iterator OriAudioCache::RequestChannel(bool &allocStatus, FMOD_CHANNELINDEX &allocMode)
{
vector<OriChannel>::iterator vOri_iter(channels_.begin());
if(vOri_iter->status() == false)
{
if(vOri_iter->channel() == 0)
{
allocMode = FMOD_CHANNEL_FREE;
vOri_iter->setStatus(true); // flag channel as being used
return vOri_iter;
}
else allocMode = FMOD_CHANNEL_REUSE;
vOri_iter->setStatus(true); // flag channel as being used
return vOri_iter;
}
else return channels_.end();
}
void OriAudioCache::ReleaseChannel(Channel *channel)
{
bool playing(false);
bool paused(false);
channel->isPlaying(&playing);
channel->getPaused(&paused);
if(!playing && !paused)
{
vector<OriChannel>::iterator vOri_iter(channels_.begin());
for(; vOri_iter != channels_.end(); ++vOri_iter)
{
if(vOri_iter->channel() == channel) vOri_iter->setStatus(false);
}
}
}
I get undefined reference errors:
findrzkeeprz#Aardvak:~/Documents/Chidori/Engine/Audio$ make
g++ -ggdb -I../../ -I../../Engine -I../../Include -I../../Public -o audio main.cpp ../../Libraries/FMODEX/libfmodex.so
/tmp/cctNhPVy.o: In function `main':
/home/findrzkeeprz/Documents/Chidori/Engine/Audio/main.cpp:9: undefined reference to `OriAudioCache::OriAudioCache(FMOD::System*, int)'
/home/findrzkeeprz/Documents/Chidori/Engine/Audio/main.cpp:12: undefined reference to `OriAudioCache::LoadSound(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, AudioLoadMode)'
/home/findrzkeeprz/Documents/Chidori/Engine/Audio/main.cpp:13: undefined reference to `OriAudioCache::FindSound(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
/home/findrzkeeprz/Documents/Chidori/Engine/Audio/main.cpp:14: undefined reference to `OriAudioCache::PlaySound(FMOD::Sound*)'
collect2: ld returned 1 exit status
make: *** [audio] Error 1
What I'm I doing wrong here?
You're compiling OriAudioCache.hpp, when you should be compiling OriAudioCache.cpp, that's assuming that file that contains the implementation.
In general, the term "Undefined reference" from a compiler (actually the linker) means that some code fragment is accessing a symbol that the linker could not find.
Common causes of these errors:
Source file containing the definition
is not included in the build process.
A source fragment (code lines) were
not removed.
A header file (class declaration)
declares the given method or symbol (which was not removed or needs to be implemented).
Incorrect or missing scope resolution
operator (namespace issue).
Build process using wrong version of
source files (e.g. file not checked
into CMS.).
Most cases of these errors are not about the C++ reference operator nor dereferencing pointers.
Solutions:
Code review by independent eye(s).
Code inspection tools: Cppcheck,
Valgrind, Klocwork, etc.
Make fewer changes, compiler more
often.
Use Test Driven Development. ;-)