Cannot convert value of type to expected argument type error

I have a swift file where I am calling objective c functions and providing pointers to certain values where needed but im getting the error " : Cannot convert value of type 'Swift.UnsafeMutablePointer<MacStat.SMCVal_t>' to expected argument type 'Swift.UnsafeMutablePointer<__ObjC.SMCVal_t>' "
Here is the relevant code block where I am getting the error:

          
        var convertRawToFahrenheit: Double = 0.0
        
        withUnsafeMutablePointer(to: &SMCValue) { pointer in
            convertRawToFahrenheit = convertToFahrenheit(val: pointer)
        }
            
            print(String(format: "Temperature: %0.1f °%c", convertRawToFahrenheit ))
            return nil
            
        } else {
            print("could not convert temperature and format values in Fahrenheit")
            return nil
        }
        return 0.0;
    }

I already have a bridging header and the path to that header set up so I know the issue Isn't anything that involves my C functions not getting recognized in swift. I will also provide my full code:

import IOKit




    
     public struct SMCVal_t {
        var datasize: UInt32
        var datatype: UInt32
        var data: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
    }
    
    @_silgen_name("openSMC")
    func openSMC() -> Int32
    
    @_silgen_name("closeSMC")
    func closeSMC() -> Int32
    
    @_silgen_name("readSMC")
    func readSMC(key: UnsafePointer<CChar>?,val: UnsafeMutablePointer<SMCVal_t>) -> kern_return_t
    
    
func convertAndPrintTempValue(key:UnsafePointer<CChar>?,scale: Character, showTemp: Bool ) -> Double? {
    
    let openSM = openSMC()
    guard openSM == 0 else {
        print("Failed to open SMC: \(openSM)")
        return 0.0;
    }
    
    let closeSM = closeSMC()
    guard closeSM == 0 else {
        print("could not close SMC: \(closeSM)")
        return 0.0;
    }
    
    
    var SMCValue = SMCVal_t(datasize: 0, datatype: 0, data:(0,0,0,0,0,0,0,0))          //initializing SMC value
    
    if let key = key {                                                                //check if nil. If not nil, proceed to code block execution
        
        let key = "TC0P"
        let keyCString = (key as NSString).utf8String                              //passing key as null terminated utf8 string
        
        let readSMCResult = readSMC(key: keyCString, val: &SMCValue)                 //call readSMC obj-C function, store result in "readSMCResult"
        
        if readSMCResult != KERN_SUCCESS  {
            print("Failed to read SMC: \(readSMCResult)")
        }
        
    }
    
    if showTemp {                                                                    //return nil if showTemp is false
          
        var convertRawToFahrenheit: Double = 0.0
        
        withUnsafeMutablePointer(to: &SMCValue) { pointer in
            convertRawToFahrenheit = convertToFahrenheit(val: pointer)
        }
            
            print(String(format: "Temperature: %0.1f °%c", convertRawToFahrenheit ))
            return nil
            
        } else {
            print("could not convert temperature and format values in Fahrenheit")
            return nil
        }
        return 0.0;
    }


Replies

It’s hard to say for sure, but it sounds like you’re declaring two copies of SMCVal_t, one in Swift and one in Objective-C.

Let’s start with the big picture. On macOS, the I/O registry is the source of all sorts of weird and wonderful info. However, only some of that is considered API. Your general guide here should be the declarations in the headers. If you need to hard code class or property names, rather than use declarations from the IOKit framework, you’re straying from the path of long-term binary compatibility.

Regarding your specific task, there’s no supported way to get temperature values from the SMC.

And with that out of the way, let’s return to the code itself.

I’m not sure what you’re trying to do with @_silgen_name but that itself is not supported. If you want to call a function declared in C, put its prototype in your bridging header.

Your SMCVal_t declaration is bogus. Swift does not offer any guarantees on struct layout. If you need that, declare the structure in C and import that into Swift.

The way you handle keyCString is suboptimal. You can pass a Swift String directly to a C const char * parameter. I talk about this in some detail in The Peril of the Ampersand.

Fahrenheit is just dumb. Oh wait, that’s not a problem with your code per se (-:

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"