Reputation: 19
I have an Xcode project where I am using C to handle a low level task so I created the C file and the bridging header. However, I am getting a linker error when I try to build my project: "Linker command failed with exit code 1 (use -v to see invocation)"
Here is my .c file :
#include <stdio.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint8_t data[32];
} SMCVal_t;
io_connect_t conn;
kern_return_t openSMC(void) {
kern_return_t result;
kern_return_t service;
io_iterator_t iterator;
service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
if(service == 0) {
printf("error: could not match dictionary");
return 0;
}
result = IOServiceOpen(service, mach_task_self(), 0, &conn);
IOObjectRelease(service);
return 0;
}
kern_return_t closeSMC(void) {
return IOServiceClose(conn);
}
double getTemperature(char *key);
kern_return_t readSMC(char *key, SMCVal_t *val) {
kern_return_t result;
uint32_t keyCode = *(uint32_t *)key;
SMCVal_t inputStruct;
SMCVal_t outputStruct;
inputStruct.datasize = sizeof(SMCVal_t);
inputStruct.datatype = 'I' << 24; //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
inputStruct.data[0] = keyCode;
result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
if (result == kIOReturnSuccess) {
if (val -> datasize > 0) {
if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) {
float temp = *(float *)val -> data;
return temp;
}
}
}
return 0.0;
}
int main(void) {
kern_return_t result;
result = openSMC();
if(result == kIOReturnSuccess) {
double temp = getTemperature("TC0P");
printf("temp: %.2f\n", temp);
result = closeSMC();
}
return 0;
}
and below here is my corresponding header file:
#ifndef getsmc_h
#define getsmc_h
#include <stdio.h>
#include <IOKit/IOKitLib.h>
typedef struct {
uint32_t datasize;
uint32_t datatype;
uint32_t data[32];
} SMCVal_t;
kern_return_t openSMC(void);
kern_return_t closeSMC(void);
kern_return_t readSMC(char *key, SMCVal_t *val);
double getTemperature(char *key);
#endif /* getsmc_h */
Upvotes: 1
Views: 110
Reputation: 634
Your C file has only the declaration line
double getTemperature(char *key);
Later, this function is accessed in your main
function in the line
double temp = getTemperature("TC0P");
Since there's no getTemperature
function for the linker to link to, this would cause a linker error to occur.
On a side note, your C file doesn't include your header file, so it doesn't have any effect on the compilation and linking.
Upvotes: 2