使用 NSString * 和 void* 移位值

Shifted value with NSString * and void*

我想将 NSString 中的 void* 传递给 NSTextField 中的方法,所以我这样做了:

(就是在OSX上的keychain access添加新密码)

 NSString *password = [passwordTextField stringValue];
UInt32 passwordlength = (UInt32) [password length];


void *mypassword = malloc(passwordlength);
mypassword = &password;

StorePasswordKeychain(mypassword, passwordlength);

问题是,例如,如果 passwordTextField returns "hello",我会返回钥匙串 "xhell"。 x 是随机的..

我认为这是一个基本问题,但我不知道如何解决它..

您不应该假设 NSString 对象如何存储它的内部表示。在您的情况下,第一个字节可能被字符串长度或其他 NSString 内部数据占用。请改用以下代码:

NSString *password = [passwordTextField stringValue];
void *mypassword = (void *)[password UTF8String];
StorePasswordKeychain(mypassword, strlen(mypassword));

如果您需要不同的编码,请使用 cStringUsingEncoding: 方法而不是 UTF8String

Keychain 不是将密码存储为字符串,而是存储为字节集合和字节数。假设您的 StorePasswordKeychainthis Apple document 中给出的示例函数的自定义版本(带有您的应用程序详细信息),那么它只是 SecKeychainAddGenericPassword 的一个简单包装器,它只需要一个指向字节的指针和字节数。

要将 NSString 转换为字节,您可以使用方法 UTF8String 将其转换为 C 风格的字符串,然后使用 C 函数 strlen 计算字节数.

const char *passwordBytes = [password UTF8String];
StorePasswordKeychain(passwordBytes, strlen(passwordBytes));

重要提示:字节数可能大于 Objective-C 字符串中的字符数,因为 Unicode 字符可能需要超过 1 个字节才能以 UTF8 格式进行编码。所以不要传递字符数(使用length方法),否则你的代码看起来可以工作但有一个细微的错误。

HTH