[swift-dev] C API Annotations outside of original header?

Saleem Abdulrasool compnerd at compnerd.org
Sun Jul 17 17:43:53 CDT 2016


On Sun, Jul 17, 2016 at 1:39 PM, Geordie J via swift-dev <
swift-dev at swift.org> wrote:

> 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.
>

AIUI, apinotes were designed specifically to address this need.  You should
be able to augment the header with an apinotes set for that header.


> 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
>
> Thanks,
> Geordie
>
> _______________________________________________
> swift-dev mailing list
> swift-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev
>
>


-- 
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20160717/9d713c13/attachment.html>


More information about the swift-dev mailing list