菜鸟教程小白 发表于 2022-12-12 21:12:46

c# - Xamarin 中的 Objective-c 绑定(bind)问题


                                            <p><p>我正在努力让我的第一个 Xamarin 绑定(bind)工作。我正在尝试创建 FlatUIKit 库的绑定(bind):<a href="https://github.com/Grouper/FlatUIKit" rel="noreferrer noopener nofollow">https://github.com/Grouper/FlatUIKit</a> .</p>

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

<p>这是包含颜色的初始 .h:</p>

<blockquote>
<p>@interface UIColor (FlatUI)</p>

<ul>
<li>(UIColor *) colorFromHexCode:(NSString *)hexString;</li>
<li>(UIColor *) turquoiseColor;</li>
<li>(UIColor *) greenSeaColor;</li>
<li>(UIColor *) emerlandColor;</li>
<li>(UIColor *) nephritisColor;</li>
<li>(UIColor *) peterRiverColor;</li>
<li>(UIColor *) belizeHoleColor;</li>
<li>(UIColor *) amethystColor;</li>
<li>(UIColor *) wisteriaColor;</li>
<li>(UIColor *) wetAsphaltColor;</li>
<li>(UIColor *) midnightBlueColor;</li>
<li>(UIColor *) sunflowerColor;</li>
<li>(UIColor *) tangerineColor;</li>
<li>(UIColor *) carrotColor;</li>
<li>(UIColor *) pumpkinColor;</li>
<li>(UIColor *) alizarinColor;</li>
<li>(UIColor *) pomegranateColor;</li>
<li>(UIColor *) cloudsColor;</li>
<li>(UIColor *) silverColor;</li>
<li>(UIColor *) concreteColor;</li>
<li><p>(UIColor *) asbestosColor;</p></li>
<li><p>(UIColor *) blendedColorWithForegroundColor:(UIColor *)foregroundColor
                            backgroundColor:(UIColor *)backgroundColor
                               percentBlend:(CGFloat) percentBlend;</p></li>
</ul>

<p>@end</p>
</blockquote>

<p>以下是 Objective Sharpie 生成的绑定(bind):</p>

<pre><code>
public partial interface FlatUI_UIColor {

   
    UIColor ColorFromHexCode (string hexString);

   
    UIColor TurquoiseColor { get; }

   
    UIColor GreenSeaColor { get; }

    /// ...

   
    UIColor BlendedColorWithForegroundColor (UIColor foregroundColor, UIColor backgroundColor, float percentBlend);
}
</code></pre>

<p>在 ApiDefintion.cs 中,我去掉了验证。</p>

<p>如果有帮助,这是初始库的 .m:</p>

<pre><code>@implementation UIColor (FlatUI)

// Thanks to http://stackoverflow.com/questions/3805177/how-to-convert-hex-rgb-color-codes-to-uicolor
+ (UIColor *) colorFromHexCode:(NSString *)hexString {
    NSString *cleanString = ;
    if ( == 3) {
      cleanString = [NSString stringWithFormat:@&#34;%@%@%@%@%@%@&#34;,
                     ,,
                     ,,
                     ,];
    }
    if( == 6) {
      cleanString = ;
    }

    unsigned int baseValue;
    [ scanHexInt:&amp;baseValue];

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

    return ;
}

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

    dispatch_once(&amp;dispatchToken, ^{
      turquoise = ;
    });

    return turquoise;
}
</code></pre>

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

<p>感谢您的帮助。</p>

<p><strong>@jstedfast 评论后更新:</strong></p>

<p>感谢您的回复。</p>

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

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

<pre><code>
</code></pre>

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

<p>生成的 .dll 看起来不错。我可以在我的示例项目中访问它的方法。我设法创建了一个带有标题的 FlatUIButton,并在运行模拟器时看到了标题。但是该按钮无法单击并且是黑色的,因为所有 FlatUI_UIColor.X 都返回 null。真不知道怎么回事。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>如果/当它们无法 P/Invoke 到 native 库中时,绑定(bind)方法通常会返回 null。所以问题可能是您在构建中根本没有与 native 库链接(或者您在模拟器上运行,例如, native 库在 FAT 二进制文件中不支持 i386),或者您有错误的链接器标志。</p>

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

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

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

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

<pre><code>
</code></pre>

<p>如果库是 c++,则需要添加:</p>

<pre><code>IsCxx = true
</code></pre>

<p>您还可以指定它依赖的框架:</p>

<pre><code>Frameworks = &#34;UIKit&#34;
</code></pre>

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

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

<p>还有其他可以设置的属性,但我不记得它们都在我的脑海中,所以你可能想检查<a href="http://docs.xamarin.com/guides/ios/advanced_topics/binding_objective-c/binding_types_reference_guide/" rel="noreferrer noopener nofollow">docs</a>获取更多可用属性(Google 可能会提供更多资源)。</p></p>
                                   
                                                <p style="font-size: 20px;">关于c# - Xamarin 中的 Objective-c 绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22883497/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22883497/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: c# - Xamarin 中的 Objective-c 绑定(bind)问题