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 */
SMCVal_tbut with a different type for the array memberdata?<stdio.h>so the header should not include<stdio.h>. Headers should be self-contained, idempotent and minimal — see Should I use#includein headers? for more information about this. Every source file (.cfile) that defines or uses any of the facilities declared in your header,getsmc.h, should include that header. Headers are the glue that ensure consistency between translation units.