I want to run a function of Cocoa's Quartz Window Services on Mac called CGWindowListCopyWindowInfo using a library called objc from Rust, is it possible?
I can't figure out how to run function it with send_msg!.
First, you're linking to the Swift version of the API, you really want the objective C version.
Second, Objective-C is for "methods" on objects, that is why send_msg! takes a subject (obj). CGWindowListCopyWindowInfo is part of a "core" service, which means it's pretty much straight C. Now I don't know if there are bindings for that, apparently Servo once maintained CG bindings but it seems like they're deprecated. You can probably BYO as if you were binding to a regular C library (by hand or using bindgen).
I would recommend learning how macOS APIs and frameworks work first, though.
Related
I'm trying to use the SwiftyChrono swift library from an Objective-C project. Since it's using a struct instead of a class (amongst many other Swift only features), I'm unable to make it work.
Given I am not in the position of moving all our Objective-C code to Swift, what are my options? Would writing a second Swift framework work, one that sits in between our app and SwiftyChrono and serves as a wrapper? Would that even work? I'm guessing if this new Swift framework was dumb enough to only perform a single function in 'Swift Land', it would play well with Objective-C?
I haven't dealt with inter-op and it really feels like a losing battle. Any help would be appreciated.
I want to call members of a C++/CLI class from native C++ code. Compiler is prohibiting me from doing that. I know that we can use native pointers/references in managed code but don't know way of going opposite. Can anyone help me with this by giving a simple example.Thanks in advance.
It can't be done. Memory layout of managed types is determined by the JIT, so unless your native code uses the CLR programming interface, it has no way of discovering and accessing them. Keeping references visible to the garbage collector is another problem, although overcoming that is more straightforward.
However it is possible to create native types with C++/CLI and those will have a memory layout fixed at compile time, so both managed and native code can use them. That is the way to cross the managed-native boundary in reverse. (Function pointers created from delegates are another way to cross in reverse)
I am working with XPC services using NSXPCConnection wrapper, and since the Objective-C wrapper can't handle IOSurfaceRef objects, I would like to make some direct functions calls to the C API defined in xpc.h. But I can't find a way to retrieve the underlying xpc_connection_t reference (as I can see in NSXPCConnection.h, there is a private ivar called _xconnection that could be the reference I need).
Am I missing something stupid, or can't the Objective-C wrapper and the C API simply be used together?
Nope, but XPCKit offers such a conversion mechanism AND it's 10.7 compatible.
How would you build a wrapper to unmanaged code in order to use it in managed code, and when exactly do you have to do that?
You don't often need a wrapper, many DLLs with straight-forward exported C functions can be pinvoked with the [DllImport] attribute. An exception for C exports would be a poorly designed DLL that requires the client code to release memory, that can't be done by the managed code since it doesn't have access to the allocator.
The case where you have to have a wrapper is a native C++ class. Managed code cannot pinvoke it directly since it doesn't know how to create an instance of the class (which requires knowing the size of the object and calling the constructor) nor how to destroy it (which requires calling the destructor). It is pretty easy to do in C++/CLI. Very mechanical, the SWIG project can do it automatically. Learning that tool is however more of an investment than learning how to write the wrapper.
Is there a recommended way to wrap a native c++ library by c++ cli?
Not sure if one size fits all, but yeah, it is largely a mechanical process. Your ref class wrapper should declare a private member that's a pointer to your native C++ class. Create the instance in the constructor. You'll need a destructor and a finalizer to delete that instance again.
Then for each function in the native C++ class you write a managed version of it. That's almost always a one-to-one call, you simply call the corresponding native method and let C++ Interop convert the arguments. Sometimes you have to write a bit of glue code to convert a managed argument to the native version of it, particularly if your native method uses 8-bit char* or structure arguments.
You'll find that standard pattern in code in my answer here. I also should mention SWIG, a tool that can automate it. Not sure how good it is, never used it myself.