OGeek|极客世界-中国程序员成长平台

标题: c# - Xamarin 中的 Objective-c 绑定(bind)问题 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 21:12
标题: c# - Xamarin 中的 Objective-c 绑定(bind)问题

我正在努力让我的第一个 Xamarin 绑定(bind)工作。我正在尝试创建 FlatUIKit 库的绑定(bind):https://github.com/Grouper/FlatUIKit .

我设法创建了上述项目的胖静态库(通用 .a)。 我使用 Objective Sharpie 为我生成 ApiDefinition.cs。 我使用该 ApiDefinition.cs 在 Xamarin 中创建了一个 BindingProject(稍作修改以使项目编译)。 我拿了那个新的 .dll 并在一个新项目中尝试了它。 从该 .dll 调用方法可以正常工作并编译。但是,我在运行时遇到问题。对 FlatUI_UIColor 进行的所有静态调用都返回 null。这使得这个 API 无法使用。

这是包含颜色的初始 .h:

@interface UIColor (FlatUI)

@end

以下是 Objective Sharpie 生成的绑定(bind):

[Category, BaseType (typeof (UIColor))]
public partial interface FlatUI_UIColor {

    [Static, Export ("colorFromHexCode:")]
    UIColor ColorFromHexCode (string hexString);

    [Static, Export ("turquoiseColor"), Verify ("ObjC method massaged into getter property", "/Users/jhondel/Projects/iOS Libraries/FlatUIKit/Classes/ios/UIColor+FlatUI.h", Line = 14)]
    UIColor TurquoiseColor { get; }

    [Static, Export ("greenSeaColor"), Verify ("ObjC method massaged into getter property", "/Users/jhondel/Projects/iOS Libraries/FlatUIKit/Classes/ios/UIColor+FlatUI.h", Line = 15)]
    UIColor GreenSeaColor { get; }

    /// ...

    [Static, Export ("blendedColorWithForegroundColor:backgroundColor:percentBlend:")]
    UIColor BlendedColorWithForegroundColor (UIColor foregroundColor, UIColor backgroundColor, float percentBlend);
}

在 ApiDefintion.cs 中,我去掉了验证。

如果有帮助,这是初始库的 .m:

@implementation UIColor (FlatUI)

// Thanks to http://stackoverflow.com/questions/3805177/how-to-convert-hex-rgb-color-codes-to-uicolor
+ (UIColor *) colorFromHexCodeNSString *)hexString {
    NSString *cleanString = [hexString stringByReplacingOccurrencesOfString"#" withString""];
    if ([cleanString length] == 3) {
        cleanString = [NSString stringWithFormat"%@%@%@%@%@%@",
                       [cleanString substringWithRange:NSMakeRange(0, 1)],[cleanString substringWithRange:NSMakeRange(0, 1)],
                       [cleanString substringWithRange:NSMakeRange(1, 1)],[cleanString substringWithRange:NSMakeRange(1, 1)],
                       [cleanString substringWithRange:NSMakeRange(2, 1)],[cleanString substringWithRange:NSMakeRange(2, 1)]];
    }
    if([cleanString length] == 6) {
        cleanString = [cleanString stringByAppendingString"ff"];
    }

    unsigned int baseValue;
    [[NSScanner scannerWithString:cleanString] scanHexInt:&baseValue];

    float red = ((baseValue >> 24) & 0xFF)/255.0f;
    float green = ((baseValue >> 16) & 0xFF)/255.0f;
    float blue = ((baseValue >> 8) & 0xFF)/255.0f;
    float alpha = ((baseValue >> 0) & 0xFF)/255.0f;

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

+ (UIColor *) turquoiseColor {
    static UIColor *turquoise = nil;
    static dispatch_once_t dispatchToken;

    dispatch_once(&dispatchToken, ^{
        turquoise = [UIColor colorFromHexCode"1ABC9C"];
    });

    return turquoise;
}

任何想法为什么 FlatUI_UIColor.GreenSeaColor(和其他)返回 null?

感谢您的帮助。

@jstedfast 评论后更新:

感谢您的回复。

我已经使用 makefile 构建了 fat 库 https://github.com/xamarin/monotouch-samples/blob/master/BindingSample/src/binding/Makefile。

它构建了一个通用库(收集了 armv7 和 i386)。
当我在 Xamarin 的绑定(bind)项目中导入这个 .a 时,它会自动生成 LinkWith。就我而言:

[assembly: LinkWith ("libXMBindingLibrarySampleUniversal.a", LinkTarget.ArmV7 | LinkTarget.Simulator, ForceLoad = true)]  

该库仅使用“UIKit”和“Foundation”,根据文档,不需要在 LinkWith 中指定。

生成的 .dll 看起来不错。我可以在我的示例项目中访问它的方法。我设法创建了一个带有标题的 FlatUIButton,并在运行模拟器时看到了标题。但是该按钮无法单击并且是黑色的,因为所有 FlatUI_UIColor.X 都返回 null。真不知道怎么回事。



Best Answer-推荐答案


如果/当它们无法 P/Invoke 到 native 库中时,绑定(bind)方法通常会返回 null。所以问题可能是您在构建中根本没有与 native 库链接(或者您在模拟器上运行,例如, native 库在 FAT 二进制文件中不支持 i386),或者您有错误的链接器标志。

有两种方法可以为 Xamarin.iOS 的 native 库指定链接器标志,但我将引导您了解我认为最简单的方法:

如果您使用的是 Xamarin Studio,并且您已经使用 Objective-C 绑定(bind)项目模板创建了一个项目,您只需添加 native 库(带有 .a 扩展名),Xamarin Studio 就会创建一个新的源文件具有与 native 库相同的基本名称但具有“.linkwith.cs”扩展名。

您需要做的是编辑该文件并进行所需的任何调整。

初始的 LinkWith 属性应该如下所示(这是凭内存得出的,因此可能不是 100% 准确):

[assembly: LinkWith ("libLibraryName.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, ForceLoad = true)]

如果库是 c++,则需要添加:

IsCxx = true

您还可以指定它依赖的框架:

Frameworks = "UIKit"

如果 native 库需要与其他 native 库链接,您可以使用 LinkerFlags 属性(字符串)指定它们。

(您只需要指定应用程序尚未链接的框架 - 因此您通常可以跳过 Foundation 和 UIKit,但这也没有什么坏处)

还有其他可以设置的属性,但我不记得它们都在我的脑海中,所以你可能想检查docs获取更多可用属性(Google 可能会提供更多资源)。

关于c# - Xamarin 中的 Objective-c 绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22883497/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://sqlite.in/) Powered by Discuz! X3.4