Calling C from swift on XCode

So, the bridging header says


#define qnorm5        Rf_qnorm5
#define qnorm qnorm5

double  qnorm(double, double, double, int, int);


and the code says


let myresult = qnorm (0.75,0,1,1,0)


This compiles, but does not link. The link output says



Undefined symbols for architecture x86_64:
  "_qnorm", referenced from:
      macOS_app_test.ViewController.sayButtonClicked(Any) -> () in ViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


The paths are correct and the proper library is found. Except that the symbol _qnorm doesn't exist anywhere. It's probably _Rf_qnorm5 that the compiler should look for. It does not seem to matter what says in the bridging header file, so I'm probably making some newbie mistake, but which?
Any and all hints or suggestions appreciated.
Thank you.

Replies

When you compile the C program, the actual name of the routine in the object file is RF_qnorm5, not qnorm. The defines in your C file are text substitutions that substitute RF_qnorm5 for qnorm. The swift compiler does not understand the C compiler pre-processor directives, so, when you want to call qnorm, it's looking for a subroutine entry named _qnorm, which it's not finding because the C compiler generated an _RF_qnorm subroutine entry.


In the C file, get rid of the #defines, and use the RF_qnorm5 name directly. Or, call RF_qnorm5 in the Swift call.

The other way to get around your problem is to still get rid of the #defines, but, define qnorm as a wrapper function around RF_qnorm5, if using RF_qnorm5 is not appropriate.

OK, this seems to work! Only … there are more unfound symbols now.


Undefined symbols for architecture x86_64:
  "_R_NaN", referenced from:
      _Rf_qnorm5 in libnmath.a(qnorm.o)
  "_R_NegInf", referenced from:
      _Rf_qnorm5 in libnmath.a(qnorm.o)
  "_R_PosInf", referenced from:
      _Rf_qnorm5 in libnmath.a(qnorm.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


From looking at the sources, the undefined symboles seem to be mathematical constants. But just declaring them as for insance


double R_NaN = (1.0/0.0);
does not work.
Any suggestions?

  • chnage c file extension from (.m or .mm or .cpp) to (.c)

Add a Comment