[swift-dev] C API Annotations outside of original header?
Geordie J
geojay at gmail.com
Sun Jul 17 15:39:14 CDT 2016
Hi, I’m hoping to add CF_SWIFT_NAME annotations to an imported Clang module (JNI) without editing the original header file itself. Is this possible, or is there a working alternative other than creating a Swift wrapper? Maybe this is trivial but C is not my strong point.
Specifically, there are a bunch of type names in the Android JNI that I’d rather just keep „Swifty“ (the CF_SWIFT_NAME additions are my own of course, working with a copy of the original file for now):
typedef unsigned char jboolean; // can be 0 or 1 - is this the same as CFBoolean?
typedef signed char jbyte CF_SWIFT_NAME(Int8);
typedef unsigned short jchar CF_SWIFT_NAME(UInt8);
typedef short jshort CF_SWIFT_NAME(Int16);
typedef int jint CF_SWIFT_NAME(Int32);
typedef long long jlong CF_SWIFT_NAME(Int);
typedef float jfloat CF_SWIFT_NAME(Float);
typedef double jdouble CF_SWIFT_NAME(Double);
Note that there’s no good way of wrapping these in pure Swift, as far as I can see (they show up throughout the rest of the APIs). Also, it’d be great if the following was possible from outside the header. Instead of:
typedef enum jobjectRefType {
JNIInvalidRefType = 0,
JNILocalRefType = 1,
JNIGlobalRefType = 2,
JNIWeakGlobalRefType = 3
} jobjectRefType;
… to use:
typedef NS_ENUM(NSInteger, jobjectRefType) {
JNIInvalidRefType CF_SWIFT_NAME(invalid) = 0,
JNILocalRefType CF_SWIFT_NAME(local) = 1,
JNIGlobalRefType CF_SWIFT_NAME(global) = 2,
JNIWeakGlobalRefType CF_SWIFT_NAME(weakGlobal) = 3
};
The final question is whether it’s at all possible to annotate this kind of API:
struct JNINativeInterface {
jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
jsize);
// and about 100 more of these ...
}
This imports into Swift as jni.DefineClass(env, string, obj, bytes, size). Attempting to put a type annotation into the header results like this:
jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, size)
CF_SWIFT_NAME(defineClass(env:name:object:byteContents:size:));
results in a strange warning: "‚swift_name‘ attribute has invalid identifier for base name“. It is possible to just rename DefineClass to e.g. defineClass, via CF_SWIFT_NAME(defineClass); I assume this is because this is a function pointer on a struct rather than a global function.
Any help regarding the above would be much appreciated. Playing around with those changes locally has made huge improvements to the readability of Android/JNI-specific Swift code. If I can find a clean solution to this I’d like to finally clean up and upstream the SwiftJNI module I started here: https://github.com/SwiftAndroid/swift-jni <https://github.com/SwiftAndroid/swift-jni>
Thanks,
Geordie
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160717/8438da24/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 455 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160717/8438da24/attachment.sig>
More information about the swift-dev
mailing list