-1

I'm passing an array of structs from Swift to a C function. The struct looks like this:

struct Struct {
    int a;
    float b;
    float c;
    const char* d;
    const char* e;
    const char* f;
    const char* g;
    int h[4];
};

Function signature of the C function:

void test(struct Struct* structs);

Weirdly, when I print d in the C function, it's often something different than what I set it to in the Swift code: usually an empty string or some garbage. When I set d to a very long string, it works correctly. The other strings are passed correctly too. Is that some struct alignment issue?

6
  • 1
    You need to show actual code that demonstrates the issue. Commented Dec 21, 2017 at 17:38
  • If this is an alignment issue, we probably need more details. What are sizeof and alignof of int and float in C? What are the actual pointer values? What compiler are you using, and for what machine? Commented Dec 21, 2017 at 17:40
  • How do you fill the struct in your Swift code? My guess would be that the char * members point to C strings which were temporarily created from Swift strings, and are already deallocated or overwritten when the C function is called. Commented Dec 21, 2017 at 18:15
  • @DanielH: The struct layout in Swift can be different from C in general, but for structures imported from C, Swift preserves the layout (sizes, alignment, padding) Commented Dec 21, 2017 at 18:43
  • @MartinR I'm passing string literals to the struct's constructor, i.e. something like Struct("test"). But it seems that your guess was correct, the C strings are overwritten by whatever is written to the stack... Commented Dec 27, 2017 at 14:01

1 Answer 1

0

As @MartinR suggested, when I pass the string to the struct's constructor, Swift creates a temporary C char array on the stack, copies the string's data into it and passes its pointer to the constructor. Immediately after that, the char array is no longer valid. Here's an example code demonstrating this:

let s = Struct(string: "string")
print(s.string) // Prints "string"
print("lol") // Overwrite the stack
print(s.string) // Prints "lol"

See https://stackoverflow.com/a/40121697/243225 for possible solutions.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.