easy petsc function call in a class - c++
The following question might be easy to answer, but I did not find any solution in the Internet. To put it in a nutshell, I put some petsc function calls in a class.
The following equation solver script works without any problems:
static char help[] = "3x3-Equation system\n\n";
#include <petscksp.h>
#undef __FUNCT__
#define __FUNCT__ "main"
int main(int argc,char **argv)
{
PetscErrorCode ierr;
PetscMPIInt rank;
PetscInt i,j,N;
PetscInt l[] = {0,1,2}; // indices for right hand vector (rhv)
PetscScalar vec[] = {0.0,5.0,3.0}; //values of rhv
PetscScalar matrix[3][3]= {{-1.0,1.0,1.0},{1.0,-3.0,-2.0},{5.0,1.0,4.0}};
Vec b,x;
Mat A;
KSP ksp; /* linear solver context */
PC pc; /* preconditioner context */
PetscInitialize(&argc,&argv,(char*)0,help);
ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
PetscPrintf(PETSC_COMM_SELF,"[%d] rank\n",rank);
//Init vector
ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr);
ierr = VecSetSizes(b,3,PETSC_DECIDE);CHKERRQ(ierr);
ierr = VecSetFromOptions(b);CHKERRQ(ierr);
ierr = VecDuplicate(b,&x);CHKERRQ(ierr);
//ierr = VecGetSize(x,&N);CHKERRQ(ierr);
//ierr = VecSet(x,vec[2]);CHKERRQ(ierr);
ierr = VecSetValues(b,3,l,vec,INSERT_VALUES);CHKERRQ(ierr);
ierr = VecAssemblyBegin(b);CHKERRQ(ierr);
ierr = VecAssemblyEnd(b);CHKERRQ(ierr);
//Init matrix
ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,3,3);CHKERRQ(ierr);
ierr = MatSetFromOptions(A);CHKERRQ(ierr);
ierr = MatSetUp(A);CHKERRQ(ierr);
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
ierr = MatSetValues(A,1,&i,1,&j,&matrix[i][j],INSERT_VALUES);CHKERRQ(ierr);
}
}
ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
//Solve
ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr);
ierr = KSPSetOperators(ksp,A,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr);
ierr = KSPSetTolerances(ksp,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
ierr = KSPView(ksp,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//View rhv
PetscPrintf(PETSC_COMM_SELF,"right hand vector:\n");
ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//View matrix
PetscPrintf(PETSC_COMM_SELF,"matrix:\n");
ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//View solution
PetscPrintf(PETSC_COMM_SELF,"solution:\n");
ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//Clean all
/*ierr = VecDestroy(&b);CHKERRQ(ierr);
ierr = VecDestroy(&x);CHKERRQ(ierr);
ierr = MatDestroy(&A);CHKERRQ(ierr);
*/
ierr = PetscFinalize();
return 0;
}
But when I outsource the code in a class, it causes several mistakes:
#include <petscksp.h>
static char help[] = "Easy equation solver\n\n";
class externSolver
{
public:
PetscErrorCode ierr;
PetscMPIInt rank;
Vec b,x;
Mat A;
KSP ksp; /* linear solver context */
PC pc; /* preconditioner context */
externSolver(int argc,char **argv)
{
ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr);
ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] rank\n",rank);CHKERRQ(ierr);
return;
}
~externSolver()
{
}
void generateMatrix(int cols, int rows)
{
ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,cols,rows);CHKERRQ(ierr);
ierr = MatSetFromOptions(A);CHKERRQ(ierr);
ierr = MatSetUp(A);CHKERRQ(ierr);
}
void MatSetValues(PetscInt num_rows,PetscInt* rows,PetscInt num_cols,PetscInt* cols,PetscScalar* Value)
{
ierr = MatSetValues(A,num_rows,rows,num_cols,cols,Value,INSERT_VALUES);CHKERRQ(ierr);
}
void assemblyMatrix()
{
ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
}
void generateVectors()
{
ierr = VecCreate(PETSC_COMM_WORLD,&b);CHKERRQ(ierr);
ierr = VecSetSizes(b,3,PETSC_DECIDE);CHKERRQ(ierr);
ierr = VecSetFromOptions(b);CHKERRQ(ierr);
ierr = VecDuplicate(b,&x);CHKERRQ(ierr);
}
void VecSetValues(PetscInt num_rows,PetscInt* rows,PetscScalar* Value)
{
ierr = VecSetValues(b,num_rows,rows,Value,INSERT_VALUES);CHKERRQ(ierr);
}
void assemblyVectors()
{
ierr = VecAssemblyBegin(b);CHKERRQ(ierr);
ierr = VecAssemblyEnd(b);CHKERRQ(ierr);
}
void solve()
{
ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr);
ierr = KSPSetOperators(ksp,A,A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr);
ierr = KSPSetTolerances(ksp,1.e-5,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT);CHKERRQ(ierr);
ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
ierr = KSPSolve(ksp,b,x);CHKERRQ(ierr);
ierr = KSPView(ksp,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
}
void showAll()
{
//View right hand vec
PetscPrintf(PETSC_COMM_SELF,"right hand vec:\n");
ierr = VecView(b,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//View matrix
PetscPrintf(PETSC_COMM_SELF,"matrix:\n");
ierr = MatView(A,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
//View solution
PetscPrintf(PETSC_COMM_SELF,"solution:\n");
ierr = VecView(x,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr);
}
void close()
{
//Clean up
ierr = VecDestroy(&b);CHKERRQ(ierr);
ierr = VecDestroy(&x);CHKERRQ(ierr);
ierr = MatDestroy(&A);CHKERRQ(ierr);
ierr = PetscFinalize();
}
};
And this is the script which calls the class:
#include "externSolver.h"
int main(int argc,char **argv)
{
PetscInt l[] = {0,1,2};
PetscScalar vec[] = {0.0,5.0,3.0};
PetscScalar matrix[3][3]= {{-1.0,1.0,1.0},{1.0,-3.0,-2.0},{5.0,1.0,4.0}};
externSolver eS(argc,argv);
//Vector
eS.generateVectors();
eS.VecSetValues(3,l,vec);
eS.assemblyVectors();
//Matrix
eS.generateMatrix(3,3);
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
eS.MatSetValues(1,&i,1,&j,&matrix[i][j]);
}
}
eS.assemblyMatrix();
//Solve Problem
eS.solve();
eS.showAll();
eS.close();
return 0;
}
These are the building mistakes:
In file included from ex2_extern.cc:5:
externSolver.h: In constructor ‘externSolver::externSolver(int, char**)’:
externSolver.h:15: error: returning a value from a constructor
externSolver.h:16: error: returning a value from a constructor
externSolver.h:17: error: returning a value from a constructor
externSolver.h: In member function ‘void externSolver::generateMatrix(int, int)’:
externSolver.h:26: error: return-statement with a value, in function returning 'void'
externSolver.h:27: error: return-statement with a value, in function returning 'void'
externSolver.h:28: error: return-statement with a value, in function returning 'void'
externSolver.h:29: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::MatSetValues(PetscInt, PetscInt*, PetscInt, PetscInt*, PetscScalar*)’:
externSolver.h:33: error: no matching function for call to ‘externSolver::MatSetValues(_p_Mat*&, PetscInt&, PetscInt*&, PetscInt&, PetscInt*&, PetscScalar*&, InsertMode)’
externSolver.h:31: note: candidates are: void externSolver::MatSetValues(PetscInt, PetscInt*, PetscInt, PetscInt*, PetscScalar*)
externSolver.h:33: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::assemblyMatrix()’:
externSolver.h:37: error: return-statement with a value, in function returning 'void'
externSolver.h:38: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::generateVectors()’:
externSolver.h:42: error: return-statement with a value, in function returning 'void'
externSolver.h:43: error: return-statement with a value, in function returning 'void'
externSolver.h:44: error: return-statement with a value, in function returning 'void'
externSolver.h:45: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::VecSetValues(PetscInt, PetscInt*, PetscScalar*)’:
externSolver.h:49: error: no matching function for call to ‘externSolver::VecSetValues(_p_Vec*&, PetscInt&, PetscInt*&, PetscScalar*&, InsertMode)’
externSolver.h:47: note: candidates are: void externSolver::VecSetValues(PetscInt, PetscInt*, PetscScalar*)
externSolver.h:49: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::assemblyVectors()’:
externSolver.h:53: error: return-statement with a value, in function returning 'void'
externSolver.h:54: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::solve()’:
externSolver.h:58: error: return-statement with a value, in function returning 'void'
externSolver.h:59: error: return-statement with a value, in function returning 'void'
externSolver.h:60: error: return-statement with a value, in function returning 'void'
externSolver.h:61: error: return-statement with a value, in function returning 'void'
externSolver.h:62: error: return-statement with a value, in function returning 'void'
externSolver.h:63: error: return-statement with a value, in function returning 'void'
externSolver.h:64: error: return-statement with a value, in function returning 'void'
externSolver.h:65: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::showAll()’:
externSolver.h:71: error: return-statement with a value, in function returning 'void'
externSolver.h:76: error: return-statement with a value, in function returning 'void'
externSolver.h:80: error: return-statement with a value, in function returning 'void'
externSolver.h: In member function ‘void externSolver::close()’:
externSolver.h:85: error: cannot convert ‘_p_Vec**’ to ‘_p_Vec*’ for argument ‘1’ to ‘PetscErrorCode VecDestroy(_p_Vec*)’
externSolver.h:85: error: return-statement with a value, in function returning 'void'
externSolver.h:86: error: cannot convert ‘_p_Vec**’ to ‘_p_Vec*’ for argument ‘1’ to ‘PetscErrorCode VecDestroy(_p_Vec*)’
externSolver.h:86: error: return-statement with a value, in function returning 'void'
externSolver.h:87: error: cannot convert ‘_p_Mat**’ to ‘_p_Mat*’ for argument ‘1’ to ‘PetscErrorCode MatDestroy(_p_Mat*)’
externSolver.h:87: error: return-statement with a value, in function returning 'void'
ex2_extern.cc: In function ‘int main(int, char**)’:
ex2_extern.cc:14: error: ‘ierr’ was not declared in this scope
ex2_extern.cc:11: warning: unused variable ‘l’
ex2_extern.cc:12: warning: unused variable ‘vec’
ex2_extern.cc:13: warning: unused variable ‘matrix’
make: [ex2_extern.o] Error 1 (ignored)
Where is the problem?
Kind regards,
Sebastian
According to CHKERRQ doc you need to use rather CHKERRV inside functions returning void or any other non-integer datatype.
I can only presume that your CHKERRQ macro expands to something like
if (ierr != 0) return ierr;
Which you could have determined by looking at the lines the compiler message worked out and then finding out what that macro did.
I don't think I dare comment on the style of this code. It just needs a serious rewrite. Taking C code and wrapping it with method calls in a class does not make it C++ code.
PETSc has provided another way to check error in function without return valus: CHKERRABORT(comm,n).
CHKERRABORT: Checks error code returned from PETSc function. If non-zero it aborts immediately.
As following said, CHKERRV will ignore error and is not recommend.
You can use CHKERRV() which returns without an error code (bad idea since the error is ignored) or CHKERRABORT(comm,n) to have MPI_Abort() returned immediately.
reference:
[1]https://petsc.org/release/docs/manualpages/Sys/CHKERRXX.html
[2]https://petsc.org/release/docs/manualpages/Sys/CHKERRABORT.html#CHKERRABORT
Related
Getting Blob data in caffe
I am trying to plot layer out of caffe as follow. int ncols = (int)(sqrt (blob.channels())); int nrows; if(blob.channels()%ncols!=0){ nrows = ncols+1; } int Rows = nrows*blob.height(); int Cols = ncols*blob.width(); cv::Mat image = cv::Mat::zeros(Rows+nrows, Cols+ncols, CV_32FC1); ///////Plotting output of individual layer if(blob.height()>1 && blob.width()>1){ cv::Size ss(blob.width(), blob.height()); Dtype* data = blob.mutable_cpu_data(); int r=0; int c=0; for(int k=0; k < blob.channels(); k++) { cv::Mat channel(ss, CV_32FC1, data); channel.copyTo(image(cv::Rect(c*blob.width()+1, r*blob.height()+1, blob.width(), blob.height()))); c++; if(c>0 &&c%ncols==0){ r++; c=0; } channel.release(); data += ss.area(); } } For that I have error as CXX src/caffe/net.cpp src/caffe/net.cpp: In instantiation of ‘void caffe::Net<Dtype>::ForwardDebugInfo(int) [with Dtype = float]’: src/caffe/net.cpp:1040:1: required from here src/caffe/net.cpp:632:49: error: passing ‘const caffe::Blob<float>’ as ‘this’ argument discards qualifiers [-fpermissive] Dtype* data = blob.mutable_cpu_data(); ^ In file included from ./include/caffe/layer.hpp:8:0, from src/caffe/net.cpp:11: ./include/caffe/blob.hpp:225:10: note: in call to ‘Dtype* caffe::Blob<Dtype>::mutable_cpu_data() [with Dtype = float]’ Dtype* mutable_cpu_data(); ^ src/caffe/net.cpp: In instantiation of ‘void caffe::Net<Dtype>::ForwardDebugInfo(int) [with Dtype = double]’: src/caffe/net.cpp:1040:1: required from here src/caffe/net.cpp:632:49: error: passing ‘const caffe::Blob<double>’ as ‘this’ argument discards qualifiers [-fpermissive] Dtype* data = blob.mutable_cpu_data(); ^ In file included from ./include/caffe/layer.hpp:8:0, from src/caffe/net.cpp:11: ./include/caffe/blob.hpp:225:10: note: in call to ‘Dtype* caffe::Blob<Dtype>::mutable_cpu_data() [with Dtype = double]’ Dtype* mutable_cpu_data(); ^ Makefile:575: recipe for target '.build_debug/src/caffe/net.o' failed make: *** [.build_debug/src/caffe/net.o] Error 1 What does that error means? Earlier version of caffe, it was fine. I did it before. Now what could be the error?
That error translates as "You pass a const object as this argument to a non-const method mutable_cpu_data" const Dtype* cpu_data() const; Dtype* mutable_cpu_data(); "Passing an object as this argument" suggests use of operators . or -> to access object's method and use of operator(). If you do that, you potentially can change const object, so it's an error, unless permissive mode engaged.
llvm createCall Calling a function with a bad signature
I want to make a function in LLVM which is an adapter with only a function call foo(idx, mn). The function prototype of foo is void foo(unsigned char, const char*). // adapter Function with only a function call foo(idx, mn) llvm::Function* createCallFun(llvm::Module* M, llvm::Function* exit_f) { llvm::LLVMContext& Ctx = M->getContext(); llvm::Function* foo_f = foo_prototype(Ctx, M); llvm::Constant* c = M->getOrInsertFunction("__call_fun", FunctionType::getVoidTy(Ctx), llvm::Type::getInt32Ty(Ctx), llvm::Type::getInt32Ty(Ctx), NULL); llvm::Function* call_fun_f = llvm::cast<llvm::Function>(c); llvm::BasicBlock* entry = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", call_fun_f); llvm::IRBuilder<> builder(entry); llvm::Function::arg_iterator args = call_fun_f->arg_begin(); llvm::Value* idx = &*args++; idx->setName("idx"); llvm::Value* mn = &*args++; mn->setName("mn"); llvm::Value* greater = builder.CreateICmpSGE(idx, mn, "tmp"); std::vector<llvm::Value*> fun_args; fun_args.push_back(greater); fun_args.push_back(err_msg); builder.CreateCall(foo_f, fun_args); return call_fun_f; } Then I got this error: lib/IR/Instructions.cpp:245: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef, llvm::ArrayRef >, const llvm::Twine&): Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed. It seems the first argument of foo has a type mismatch. How can I cast the Value greater to unsigned char type?
I fixed this error by cast greater with CreateZExt. llvm::Value *castuchar = builder.CreateZExt(greater, llvm::Type::getInt8Ty(Ctx), "tmp1");
Vectors in myclass. error: parenthesized initializer in array new [-fpermissive]
I'm new to C++ class BlenderMesh{ public: std::vector<double[3]> vertex_vectors; std::vector<double[3]> normal_vectors; std::vector<double[2]> uv_vectors; std::vector<std::string> texture_list; std::vector<int[6]> face_indices; std::vector<int[3]> normal_indices; std::vector<int[3]> uv_indices; BlenderMesh(); ~BlenderMesh();}; Error in code: mesh->vertex_vectors.push_back(vertex); BlenderMesh::BlenderMesh(){} BlenderMesh::~BlenderMesh(){} BlenderMesh* mesh = new BlenderMesh(); PyObject* vertexVectors = PyList_GetItem(blenderObject,2); unsigned int size_vertex_vectors = PyObject_Size(vertexVectors); for (unsigned int i = 0; i < size_vertex_vectors; i++){ double vertex[3]; PyObject* pyVertex = PyList_GetItem(vertexVectors,i); PyObject* vertexX = PyTuple_GetItem(pyVertex,0); vertex[0] = PyFloat_AsDouble(vertexX); PyObject* vertexY = PyTuple_GetItem(pyVertex,1); vertex[1] = PyFloat_AsDouble(vertexY); PyObject* vertexZ = PyTuple_GetItem(pyVertex,2); vertex[2] = PyFloat_AsDouble(vertexZ); mesh->vertex_vectors.push_back(vertex); } Console: /usr/include/c++/4.9.2/ext/new_allocator.h:120:4: error: parenthesized initializer in array new [-fpermissive] { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } /usr/include/c++/4.9.2/ext/new_allocator.h:124:29: error: request for member '~double [3]' in '* __p', which is of non-class type 'double [3]' destroy(_Up* __p) { __p->~_Up(); }
Well it has been four years but hopefully this helps someone. For some reason you are not able to create a vector object containing a native list of objects (maybe someone could explain why?). So, for example, when creating a 18x2 vector containing 1'ns for example: std::vector<double[2]> my_vector(18, {1.0, 1.0}); So instead you should to the following: std::vector<vector<double>> my_vector(18, vector<double>(2,{1.0, 1.0});
In C++11, a std::array can be used: std::vector<std::array<double,2>> my_vector(18, std::array<double,2>{1.0, 1.0});
request for member ‘begin’ in ‘ionDistance’, which is of non-class type ‘float*’
I have written the code below and I am receiving the error. What am I doing wrong? float sampledEnergies ( float ionDistance[], float ionEnergy[]) { float samTime[1000]; float simPos[1000]; float closeEnergy[1000]; float close; int maxSamples = chamberLength / (driftVel * adcSampleRate); for (int i = 0; i < maxSamples; i++) { samTime[i] = i * adcSampleRate; simPos[i] = chamberLength - (driftVel * samTime[i]); printf("%.2f\t%.2f\n",samTime[i],simPos[i]); close = lower_bound(ionDistance.begin(),ionDistance.end(), simPos[i]); for (int j = 0; j < maxSamples; j++) { if (close = ionDistance[j]) { closeEnergy[i] = ionEnergy[j]; } } } } The above is the code and the error is as follows. TBraggSimulation_v1.cpp: In function ‘float sampledEnergies(float*, float*)’: TBraggSimulation_v1.cpp:37: error: request for member ‘begin’ in ‘ionDistance’, which is of non-class type ‘float*’ TBraggSimulation_v1.cpp:37: error: request for member ‘end’ in ‘ionDistance’, which is of non-class type ‘float*’
Your ionDistance is a pointer (to a first element of an array) and not a standard-library container. Your code tries to call begin and end, which are only defined for containers. To obtain a range of iterators for a pointer, use: lower_bound(ionDistance, ionDistance + n, simPos[i]); Here n is the number of elements in your ionDistance array. I don't understand your code enough to suggest it's equal to maxSamples; if it's not, add a parameter to your function: float sampledEnergies ( float ionDistance[], float ionEnergy[], size_t numIons) { lower_bound(ionDistance,ionDistance + numIons, simPos[i]); }
PJSUA Makefile error: Invalid use of non-static data member 'param'
Working with pjsua and the pjsua-jni folder I have run into a error. Being new to C and C++ I have just learning as I go. I have experience with programming so I am not that out of my league, I hope. The errors I get from the make file is nativesrc/pjsua_wrap.cpp:3843:23: error: invalid use of non-static data member 'param' pjmedia_codec_fmtp::param *arg2 ; ~~~~~~~~~~~~~~~~~~~~^~~~~ nativesrc/pjsua_wrap.cpp:3843:30: error: use of undeclared identifier 'arg2' pjmedia_codec_fmtp::param *arg2 ; ^ nativesrc/pjsua_wrap.cpp:3849:3: error: use of undeclared identifier 'arg2' arg2 = *(pjmedia_codec_fmtp::param **)&jarg2; ^ nativesrc/pjsua_wrap.cpp:3849:32: error: invalid use of non-static data member 'param' arg2 = *(pjmedia_codec_fmtp::param **)&jarg2; ~~~~~~~~~~~~~~~~~~~~^~~~~ nativesrc/pjsua_wrap.cpp:3849:40: error: expected expression arg2 = *(pjmedia_codec_fmtp::param **)&jarg2; ^ nativesrc/pjsua_wrap.cpp:3852:25: error: invalid use of non-static data member 'param' pjmedia_codec_fmtp::param *b = (pjmedia_codec_fmtp::param *) arg1->param; ~~~~~~~~~~~~~~~~~~~~^~~~~ nativesrc/pjsua_wrap.cpp:3852:32: error: use of undeclared identifier 'b' pjmedia_codec_fmtp::param *b = (pjmedia_codec_fmtp::param *) arg1->param; ^ nativesrc/pjsua_wrap.cpp:3852:57: error: invalid use of non-static data member 'param' pjmedia_codec_fmtp::param *b = (pjmedia_codec_fmtp::param *) arg1->param; ~~~~~~~~~~~~~~~~~~~~^~~~~ nativesrc/pjsua_wrap.cpp:3852:64: error: expected expression pjmedia_codec_fmtp::param *b = (pjmedia_codec_fmtp::param *) arg1->param; ^ nativesrc/pjsua_wrap.cpp:3853:40: error: use of undeclared identifier 'b' for (ii = 0; ii < (size_t)8; ii++) b[ii] = *((pjmedia_codec_fmtp::param *) arg2 + ii); ^ nativesrc/pjsua_wrap.cpp:3853:71: error: invalid use of non-static data member 'param' for (ii = 0; ii < (size_t)8; ii++) b[ii] = *((pjmedia_codec_fmtp::param *) arg2 + ii); ~~~~~~~~~~~~~~~~~~~~^~~~~ nativesrc/pjsua_wrap.cpp:3853:78: error: expected expression for (ii = 0; ii < (size_t)8; ii++) b[ii] = *((pjmedia_codec_fmtp::param *) arg2 + ii); I am not sure how to declare this param. When looking in the codecs.h file I find this typedef struct pjmedia_codec_fmtp { pj_uint8_t cnt; /**< Number of parameters. */ struct param { pj_str_t name; /**< Parameter name. */ pj_str_t val; /**< Parameter value. */ } param [PJMEDIA_CODEC_MAX_FMTP_CNT]; /**< The parameters. */ } pjmedia_codec_fmtp; So the way its calling the param struct is pjmedia_codec_fmtp::param *arg2. Is that right? I know that the :: usually is how you call a static method but is that how you call structs too? Anyway help would be great This is the code it throws the first error on pjmedia_codec_fmtp *arg1 = (pjmedia_codec_fmtp *) 0 ; pjmedia_codec_fmtp::param *arg2; // Error