I am learning C++ and have been given an assignment to create a Vector3D class. When I try to compile main.cpp using G++ on OSX I get the following error message. Why would this be?
g++ main.cpp
Undefined symbols for architecture x86_64:
"Vector3DStack::Vector3DStack(double, double, double)", referenced from:
_main in cc9dsPbh.o
ld: symbol(s) not found for architecture x86_64
main.cpp
#include <iostream>;
#include "Vector3DStack.h";
using namespace std;
int main() {
double x, y, z;
x = 1.0, y = 2.0, z = 3.0;
Vector3DStack v (x, y, z);
return 0;
}
Vector3DStack.h
class Vector3DStack {
public:
Vector3DStack (double, double, double);
double getX ();
double getY ();
double getZ ();
double getMagnitude();
protected:
double x, y, z;
};
Vector3DStack.cpp
#include <math.h>;
#include "Vector3DStack.h";
Vector3DStack::Vector3DStack (double a, double b, double c) {
x = a;
y = b;
z = c;
}
double Vector3DStack::getX () {
return x;
}
double Vector3DStack::getY () {
return y;
}
double Vector3DStack::getZ () {
return z;
}
double Vector3DStack::getMangitude () {
return sqrt (pow (x, 2) * pow (y, 2) * pow (z, 2));
}
You have to compile and link your Vector3DStack.cpp as well. Try:
g++ main.cpp Vector3DStack.cpp -o vectortest
This should create an executable called vectortest.
Pass the implementation of Vector3D to the compiler:
g++ main.cpp Vector3DStack.cpp
This will produce executable called a.out on Linux and Unix systems. To change the executable name use -o option:
g++ -o my_program main.cpp Vector3DStack.cpp
This is the simplest possible way of building your program. You should learn a bit more - read about make program, or even cmake.
I had ran into a similar issue when writing my own implementation of a hashTable with templates.
In your main.cpp, just include "Vector3DStack.cpp", which includes Vector3DStack.h, instead of just including Vector3DStack.h.
In my case, since templates, as we know, are evaluated at compile time, having templatized (including fully specialized) methods in the class as part of the cpp file (where they are defined) need to be known to the compiler. Some of the C++ gotchas.. so much to remember, easy to forget the little things.
Mostly likely you've already got our solution, thanks to the answers posted earlier, but my $0.02 anyways.
Happy C++ Programming!
Related
Here is my problem:
I need to design a program in F# that, from a C++ program, performs simple 3D vector calculations. I don't share the calculations on the codes below because the problem stops at creating the vectors according to the printfn.
So I think it's an error, but my schoolmate on macOS has no problem with this and can run the code correctly. I deduced that it was a Windows problem, probably because of the pointers. So I'm relying on you to help me.
Thanks a lot.
PS: dotnet version 7.0.101
clang version 15.0.5
Vector3.cpp
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
return 0;
}
class Vector3
{
public:
double X;
double Y;
double Z;
Vector3(double x, double y, double z) : X(x), Y(y), Z(z) {}
};
extern "C" Vector3* CreateVector3(double x, double y, double z)
{
Vector3* v = new Vector3(x, y, z);
return v;
}
Program.fs
open System.Runtime.InteropServices
[<StructLayout(LayoutKind.Sequential)>]
printfn("test 1: Launching the program")
type Vector3 =
val mutable X: double
val mutable Y: double
val mutable Z: double
new(x, y, z) = { X = x; Y = y; Z = z }
[<DllImport("compiledVector3.exe")>]
extern Vector3 CreateVector3(double x, double y, double z)
[<DllImport("compiledVector3.exe")>]
extern double GetX(Vector3 v)
[<DllImport("compiledVector3.exe")>]
extern double GetY(Vector3 v)
[<DllImport("compiledVector3.exe")>]
extern double GetZ(Vector3 v)
[<DllImport("compiledVector3.exe")>]
extern double distanceTo(Vector3 v,Vector3 v2)
[<DllImport("compiledVector3.exe")>]
extern void vectorMovement(Vector3 v,double plusx, double plusy, double plusz)
[<DllImport("compiledVector3.exe")>]
extern Vector3 midpoint(Vector3 v,Vector3 v2)
[<DllImport("compiledVector3.exe")>]
extern double percentDistance(Vector3 pos1, Vector3 pos2, double percent)
printfn("test 2: DLL imported")
let FstVector= CreateVector3(0.0, 0.0, 0.0)
let SndVector= CreateVector3(1.0, 2.0, 3.0)
printfn("test 3: Vectors created")
I tried to launc the Program.fs with a basic dotnet run command, expecting to see in my terminal the following lines:
test 1: Launching the program
test 2: DLL imported
test 3: Vectors created
but there isn't the third line.
Terminal
PS C:\Users\AlexisLasselin\Documents\GitHub\2022-2023-project-3-harfang3d-binding-Project-4-group\CppToFs\Vector3> dotnet run
test 1: Launching the program
test 2: DLL imported
PS C:\Users\AlexisLasselin\Documents\GitHub\2022-2023-project-3-harfang3d-binding-Project-4-group\CppToFs\Vector3>
I think the compilation of your dll file is made for architecture x32 and you want to compile with a x64 windows architecture :
To compile a DLL using g++ for a 64-bit architecture, you can use the following command:
g++ -shared -o <filename>.dll -m64 <source files>
Replace with the desired name of the DLL, and with the names of the source files that make up the DLL.
The -shared option tells g++ to create a shared library (i.e., a DLL), and the -o option specifies the name of the output file. The -m64 option specifies that you want to compile for a 64-bit architecture.
Is it possible to load an extra helper .so during current gdb session?
// point.h
class Point
{
public:
int x;
int y;
Point(int x1, int y1) {x = x1; y = y1;}
};
// main.cpp
#include "point.h"
#include <stdio.h>
int main()
{
Point p(3, 4);
printf("%d\n", p.x);
return 0;
}
g++ -g -c main.cpp -o main.o
g++ -g main.o -o main
When debugging, I need to add a helper function to dump the Point object. But I don't want to recompile and rerun. (It might take a long time.) So I am trying to build another helper.so.
// helper.cpp
#include "point.h"
#include <stdio.h>
void dump_point(Point *p)
{
printf("Point(%d, %d)\n", p->x, p->y);
}
g++ -g -fPIC -shared helper.cpp -o helper.so
Is it possible to load this helper.so in gdb so I can call dump_point() without rerunning?
When debugging, I need to add a helper function to dump the Point object.
The "normal" way to do this to write a custom pretty printer in Python.
One advantage of doing that is that the pretty printer will also work for a core dump, whereas dump_point() solution will not (regardless of whether it's linked in or loaded from a separate .so).
So I am trying to build another helper.so.
If your main was linked against libdl, you could do this:
(gdb) call dlopen("./helper.so", 0)
(gdb) call dlsym($_, "dump_point")
Note: you will want to make dump_point extern "C" to avoid name mangling.
I am trying to expose a C++ DLL to Excel using mac. The DLL was written and compiled with Xcode 4 and I am using Excel 2011.
For simple functions, extern "C" does the work and I am able to use the dylib in Excel. Specifically, if the C++ code is something like
extern "C"
{
double sumC( double a, double b)
{
return a + b;
}
}
and the VBA code is:
Private Declare Function addFunction _
Lib "Macintosh HD:Users:SVM:Documents:Excel:lib:libTestDLLtoVBA.dylib" _
Alias "sumC" (ByVal a As Double, ByVal b As Double) As Double
Function Addition(a As Double, b As Double)
Addition = addFunction(a, b)
End Function
everything works fine. But, I am interested in exposing to Excel more complex code with classes defined in header files - as in the example below - and in that case Excel returns #VALUE!. My C++ code is something like this
header file:
#ifndef TestDLLtoVBA_TestFunction_h
#define TestDLLtoVBA_TestFunction_h
class AdditionVBATest{
public:
AdditionVBATest(){};
AdditionVBATest( double ){ m_AdditionResult = 0.0; }
~AdditionVBATest(){};
void setResult( double nAddition ){ m_AdditionResult = nAddition; }
double getResult(){ return m_AdditionResult; }
void addFunct( double x, double y, double &nResult );
double addFunct( double, double );
private:
double m_AdditionResult;
};
double addFunctionC( double a, double b);
#endif
cpp file:
#include <iostream>
#include "TestFunction.h"
void AdditionVBATest::addFunct(double x, double y, double &nResult)
{
nResult = 0.0;
nResult = x + y;
AdditionVBATest::setResult(nResult);
}
double AdditionVBATest::addFunct( double a, double b )
{
double nResult(0.0);
AdditionVBATest addCompute;
addCompute.AdditionVBATest::addFunct(a, b, nResult);
AdditionVBATest addResult;
return addResult.getResult();
}
And finally this is the file that contains the function I would like to expose to Excel:
#include <iostream>
#include "TestFunction.h"
extern "C"
{
double addFunctionC( double a, double b)
{
AdditionVBATest *resAddition;
double result(0.0);
result = resAddition->AdditionVBATest::addFunct(a, b);
return result;
}
}
I tried to use the same dylib in a C++ app and works fine, so I believe it is something related to exposing the library through VBA.
The VBA code I used is
Private Declare Function addFunction _
Lib "Macintosh HD:Users:SVM:Documents:Excel:lib:libTestDLLtoVBA.dylib" Alias "addFunctionC" _
(ByVal a As Double, ByVal b As Double) As Double
Function Addition(a As Double, b As Double)
Addition = addFunction(a, b)
End Function
Any help would be greatly appreciated.
This is of course not necessary but to simplify I will assume from now on that your header file and both source files are in the same directory, and that all future commands are executed in this directory. Then replace in both source files
#include "TestFunction.h"
with
#include "./TestFunction.h"
Then, compile as follows :
g++ -m32 -Wall -g -c ./TestFunction.cpp -o ./TestFunction.o
g++ -m32 -dynamiclib ./file.cpp ./TestFunction.o -o ./libTestDLLtoVBA.dylib
where
g++ is your gcc. I guess it is clang's one, on my computer it is gcc 5.2.0, but both should work fine
file.cpp is the source file containing the declaration of addFunctionC
the -m32 option asks to produce a 32 bits dylib, as excel/VBA on mac are 32 bits
Now do a nm -gU libTestDLLtoVBA.dylib and you will see a line with _addFunctionC showing that the function addFunctionC is exported indeed.
In the VBA, declare as follows :
Declare Function addFunctionC Lib "/Path/to/your/libTestDLLtoVBA.dylib" (ByVal x As Double, ByVal y As Double) As Double
Function Addition(a As Double, b As Double)
Addition = addFunction(a, b)
End Function
and it should work. This was a great source of inspiration.
Now, if you don't want to used command line and want to use XCode for instance, I would say that the only thing you have to take care of is to ensure that XCode produces a 32 bits dylib, as excel/VBA are 32 bits only on mac OS X. I really think that this 32 bits stuff is your problem.
You likely want to read up on COM automation objects. Sometimes known as "OLE" or "ActiveX". It's essentially a way to expose classes and objects written in C++ to other programming languages.
For scripting environments (VBA and Javascript), the traditional way to do this is by registering a COM object that exposes an IDispatch interface.
Some links to get you started:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms221375(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms221326(v=vs.85).aspx
Don't get hung up on the details of "controls" and embedded UI windows. Foucs on getting a simple COM object class and interface declared in an IDL, generate a typelib, implement a C++ class that implements the interface and IDispatch. ATL (Active Template Library) makes this stuff easy.
I'm trying to create a class of complex numbers in C++, but I'm getting a strange error for the initialiser of the class here is a screenshot of the error :
And here is my code :
main.cpp :
#include <iostream>
#include "cmath"
#include "Complexx.h"
int main(int argc, const char * argv[])
{
complex c(1,1);
std::cout << c.realPart << "+" <<c.imaginaryPart << "i";
return 0;
}
Complexx.h :
#ifndef Functions_Complexx_h
#define Functions_Complexx_h
#include "cmath"
using namespace std;
class complex {
public:
double imaginaryPart;
double realPart;
complex(double realPart, double imaginaryPart);
double modulus();
};
#endif
What am I doing wrong here?
The problem is here.
complex(double realPart, double imaginaryPart);
You've declared a constructor, but you haven't defined it. That's why the linker is complaining about undefined symbol complex::complex(double, double)
This is probably the definition you want - to store those two parameters in the object.
complex(double realPart, double imaginaryPart)
: realPart(realPart)
, imaginaryPart(imaginaryPart)
{ }
It doesn't matter what those parameters are named. C++ will not infer that because they have the same names as your member variables that they should be copied to the object.
You haven't provided a definition for the complex(double, double) constructor, although a declaration is provided. This is what the linker complains about.
Add this to a .cpp file in your project which #includes your header file complexx.h (possibly complexx.cpp):
complex::complex(double realPart, double imaginaryPart)
:
realPart(realPart),
imaginaryPart(imaginaryPart)
{ }
It is possible that the same problem exists for double modulus(), for which no linker error is issued because you are not invoking it (yet).
It seems that you haven't linked the definition of the complex(double, double) constructor.
This may be caused by the fact that you forgot to link Complexx.cpp (assuming the name of the cpp file is the same as the header file) or that you totally forgot to define the constructor inside the linked Complexx.cpp file.
Just run this g++ commands when compiling main.cpp (assuming you are using gcc):
g++ -c Complexx.cpp -o Complexx.o
g++ -c main.cpp -o main.o
g++ main.o Complexx.o -o app
I've recently moved over to a mac, and am struggling using the command line compilers. I'm using g++ to compile, and this builds a single source file fine. if I try to add a custom header file, when I try to compile using g++ I get undefined symbols for architecture i386. The programs compile fine in xCode however. Am I missing something obvious?
tried using g++ -m32 main.cpp... didn't know what else to try.
Okay, The old code compiled... Have narrowed it down to my constructors.
class Matrix{
public:
int a;
int deter;
Matrix();
int det();
};
#include "matrix.h"
Matrix::Matrix(){
a = 0;
deter = 0;
}
int Matrix::det(){
return 0;
}
my error is
Undefined symbols for architecture x86_64:
"Matrix::Matrix()", referenced from:
_main in ccBWK2wB.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
my main code has
#include "matrix.h"
int main(){
Matrix m;
return 0;
}
along with the usual
It looks like you’ve got three files:
matrix.h, a header file that declares the Matrix class;
matrix.cpp, a source file that implements Matrix methods;
main.cpp, a source file that defines main() and uses the Matrix class.
In order to produce an executable with all symbols, you need to compile both .cpp files and link them together.
An easy way to do this is to specify them both in your g++ or clang++ invocation. For instance:
clang++ matrix.cpp main.cpp -o programName
or, if you prefer to use g++ — which Apple haven’t updated in a while, and it looks like they won’t in the foreseeable future:
g++ matrix.cpp main.cpp -o programName
is not the case here, but it may happen to be the you forget to put the class name with ::
for example:
a good format:
foo.h
class Foo{
public:
Foo();
void say();
private:
int x;
};
foo.cpp
Foo::Foo(){
this->x = 1;
}
void Foo::say(){
printf("I said!\n");
}
a bad format
foo.h
class Foo{
public:
Foo();
void say();
private:
int x;
}
foo.cpp
Foo::Foo(){
this->x = 1;
}
//I always mistake here because I forget to put the class name with :: and the xcode don't show this error.
void say(){
printf("I said!\n");
}
Did you actually define the Box constructor somewhere? (like Line.cpp)