somu
(somu)
1
Hi,
Overview:
- I have a
C file which contains a fixed size array a1 which I would like to access from Swift.
- There is a corresponding header file in which
a1 is declared as external
- I have included the header file in the bridging header.
Problem:
- The external fixed size array
a1 declared in the header file is not accessible in main.swift.
- The problem occurs only when the header file declares the array as external instead of defining it in the header file.
In the following scenarios there are no compilation errors:
- Accessing the
int variable i1.
- When the array
a1 is defined in the header file instead of marking it as extern in header, then there is no compilation error.
Question:
- What should I do to make it accessible ?
- Am I missing something ?
Thanks.
Code:
main.swift
import Foundation
print(i1) //This compiles fine
//print(a1) //Compilation Error: Use of unresolved identifier 'a1'
Car.h
#ifndef Car_h
#define Car_h
extern int i1;
extern int a1[]; //external array is what is causing the issue
#endif /* Car_h */
Car.c
#include "Car.h"
int i1 = 20;
int a1[] = { 1, 2, 3};
TestC-Bridging-Header.h
#include "Car.h"
Note: I have edited the question, to isolate the problem.
scanon
(Steve Canon)
2
This probably ought to work (I think we should import a1 as UnsafeMutablePointer<CInt>, but it looks like we simply don't). As a work-around you can make explicit that it's "really just a pointer":
car.h
extern int i1;
extern int *a1p;
car.c
int a1[] = { 1, 2, 3 };
int a1p = a1;
main.swift
// a1p is imported as UnsafeMutablePointer<CInt>!
a1p[1] // 2
If you can spare a few moments, this would be worth writing up on bugs.swift.org. Otherwise, I'll probably do so sometime later today.
1 Like
somu
(somu)
3
@scanon Thanks a ton!!! I was breaking my head over it.
Just curious, is there a reason why extern int a1[]; wasn't accessible ? Is it a bug ?
Note: I have edited the question, to highlight what works.
scanon
(Steve Canon)
4
I haven't investigated, but my guess is that the importer simply doesn't implement support for array-of-unspecified-length declarations, as they're a somewhat niche feature of C (in particular, they're not used much--or at all?--in Apple's SDK headers). This should be pretty easy to implement (basically we just need to teach the importer that it's just a pointer), so there's a fairly high chance of it getting fixed if you file a bug report =)
2 Likes
somu
(somu)
5
2 Likes
scanon
(Steve Canon)
6
Doing a little archaeology, I find the following (lib/ClangImporter/ImportType.cpp:487):
ImportResult VisitArrayType(const clang::ArrayType *type) {
// FIXME: Array types will need to be mapped differently depending on
// context.
return Type();
}
With the commit message (Dec. 2012) from @Douglas_Gregor "C array types effectively have different behavior in different contexts; don't try to map them now." So this may be a little bit thornier to resolve than I thought at first, but we should still still probably do it (but: I'm not entirely convinced that simply decaying them to Unsafe[Mutable]Pointer<T> isn't the best option).
3 Likes
somu
(somu)
7
@scanon Thanks a lot for investigating into it and updating on the issue!