I’m making an attempt to combine the VICE emulator’s libretro core (vice_x64sc_libretro_ios.dylib) into my iOS app utilizing Swift. The core gives a perform retro_load_game
that I load dynamically utilizing dlsym()
. Nonetheless, when I attempt to name this perform, I get a crash (EXC_BAD_ACCESS
).
From the VICE emulator supply code, the perform I’m making an attempt to name is outlined as:
bool retro_load_game(const struct retro_game_info *sport);
The retro_game_info
struct is outlined as:
struct retro_game_info {
const char *path; // UTF-8 encoded file path
const void *information; // Reminiscence buffer of the sport file (NULL if fullpath mode is used)
size_t dimension; // Measurement of the reminiscence buffer
const char *meta; // Meta data (NULL if not used)
};
I load the .dylib, get a pointer to retro_load_game
, after which name it with a correctly allotted retro_game_info
struct:
import UIKit
class ViewController: UIViewController {
var core: UnsafeMutableRawPointer?
override func viewDidLoad() {
tremendous.viewDidLoad()
setupEmulator()
}
func setupEmulator() {
let corePath = Bundle.foremost.bundlePath + "/Frameworks/vice_x64sc_libretro_ios.dylib"
if FileManager.default.fileExists(atPath: corePath) {
core = dlopen(corePath, RTLD_LAZY)
if core == nil {
return
}
if let filePath = Bundle.foremost.path(forResource: "SomePrg", ofType: "prg") {
loadGame(filePath)
}
}
}
func loadGame(_ filePath: String) {
guard let core = self.core else {
return
}
if let retroLoadGamePtr = dlsym(core, "retro_load_game") {
typealias RetroLoadGameFunc = @conference(c) (UnsafeRawPointer?) -> Int32
let retroLoadGame = unsafeBitCast(retroLoadGamePtr, to: RetroLoadGameFunc.self)
if let fileData = attempt? Information(contentsOf: URL(fileURLWithPath: filePath)) {
let pathCString = strdup(filePath)
let dataPointer = malloc(fileData.rely)
if let pathCString = pathCString, let dataPointer = dataPointer {
fileData.copyBytes(to: dataPointer.assumingMemoryBound(to: UInt8.self), rely: fileData.rely)
var gameInfo = retro_game_info(
path: pathCString,
information: dataPointer,
dimension: fileData.rely,
meta: nil
)
let consequence = retroLoadGame(UnsafeRawPointer(&gameInfo)) // Crashes right here
free(pathCString)
free(dataPointer)
}
}
}
}
}
struct retro_game_info {
let path: UnsafePointer?
let information: UnsafeRawPointer?
let dimension: size_t
let meta: UnsafePointer?
}
I get EXC_BAD_ACCESS (code=1, handle=0x0)
at:
let consequence = retroLoadGame(UnsafeRawPointer(&gameInfo))
I’ve checked:
dlopen()
efficiently masses the .dylibdlsym()
efficiently findsretro_load_game
gameInfo.path
andgameInfo.information
are allotted earlier than callingretro_load_game
- I free allotted reminiscence after the perform name
So:
- Is my Swift
retro_game_info
struct accurately matching the C struct? - Is
UnsafeRawPointer(&gameInfo)
the proper approach to cross this struct toretro_load_game
? - Am I lacking any reminiscence alignment points that would trigger
EXC_BAD_ACCESS
? - Is there a greater approach to debug why
retro_load_game
is failing?