如何在Xamarin.iOS中包装Objective-C库?

时间:2016-04-20 21:58:07

标签: c# objective-c xamarin xamarin.ios

头文件包含以下内容:

#include <Foundation/Foundation.h>

FOUNDATION_EXPORT NSString* GoGopherExecute(NSString* action, NSString* data);

我看了How do I correctly wrap native c library in Xamarin.iOS,这似乎与我想做的最接近。我也看过Xamarin网站上的资源https://developer.xamarin.com/guides/cross-platform/macios/binding/objective-c-libraries/。我的ApiDefinition.cs

中有以下内容
[DllImport("Gopher.a", 
    EntryPoint="GoGopherExecute", 
    CallingConvention = CallingConvention.Cdecl)]
public static NSString GoExecute(NSString action, NSString data);

我得到的错误是“意外的符号'NSString',期待'class','delegate','enum','interface','partial'或'struct'”。我应该在ApiDefinition.cs中拥有什么?

2 个答案:

答案 0 :(得分:3)

在您离开时,您需要一些额外的步骤才能让它完全正常工作。但首先,您需要掌握Xamarin.iOS绑定项目的一些概念。

这是Xamarin.iOS绑定项目结构:

enter image description here

大多数情况下,您只需要项目模板附带的两个文件(我手动添加了Extras.cs):

来自Xamarin Documentation

的报价
  

ApiDefinition.cs :只包含名称空间和接口定义(包含接口可以包含的任何成员),不应包含类,枚举,委托或结构。 API定义文件仅仅是用于生成API的合同。

     

StructsAndEnums.cs :API定义文件所需的任何枚举,类型和结构。

因此, ApiDefinition 中需要注意的一点是,它只能包含 ObjC 定义,因此必须将上面的代码添加到其他c#代码文件中,因为它是一个 c 函数,只需在绑定项目中添加一个新类我倾向于将此文件命名为 Extras.cs (您可以将其命名为最佳状态。)< / p>

// Extras.cs contents
using System;
using System.Runtime.InteropServices;
using Foundation;
using ObjCRuntime;

namespace FooBinding {
    public static class GoGopherCFuncs {
        // FOUNDATION_EXPORT NSString* GoGopherExecute(NSString* action, NSString* data);
        [DllImport ("__Internal", EntryPoint= "GoGopherExecute")]
        static extern IntPtr _GoExecute (IntPtr action, IntPtr data);

        public static string GoExecute (string action, string data)
        {
            // Avoid creating any unused managed refs of NSString and get a handle directly
            // from our managed NET strings
            IntPtr actionPtr = NSString.CreateNative (action);
            IntPtr dataPtr = NSString.CreateNative (data);

            IntPtr ptr = _GoExecute (actionPtr, dataPtr);

            // Manually release our native NSString handles
            NSString.ReleaseNative (actionPtr);
            NSString.ReleaseNative (dataPtr);

            // Return a NET string from our unmanaged handle returned by _GoExecute.
            return (string) Runtime.GetNSObject<NSString> (ptr);
        }
    }
}

因此,上面的代码应足以解决您的问题并让您开始绑定任何其他c API。

您需要在DllImport属性中修改其他内容,您需要将dllName更改为__Internal这是因为Gopher.a可能是Gopher.a一个静态库(您可以检查this other answer以确认它是否是静态库)因此它将“合并”到您的主可执行文件中,因此您只需要将[ "$RESULT2" = "$RESULT2" ] 添加到绑定项目中在Xamarin Documentation中描述。

来自Xamarin Documentation

的报价
  

要完成此绑定,您应该将本机库添加到项目中。您可以通过将本机库添加到项目中来实现此目的,方法是将本机库从Finder拖放到解决方案资源管理器中的项目中...

我真的鼓励你阅读Xamarin Documentation:)

希望这有帮助!

答案 1 :(得分:1)

看起来你把这个方法放在了任何一个类之外。你应该转移到一个类,因为在C#中,没有类的方法就不能存在。

var https = require('https');

var cred = new Buffer("xxx:yyy").toString('base64');

var headers = {Authorization: "Basic "+cred, "Content-Type": "application/json"};
var productId = 1925263361;
var options = {
  host: 'kotntest1.myshopify.com',
  port: 443,
  path: '/admin/products/'+productId +'.json',
  method: 'PUT',
  headers: headers
};

// Setup the request.  The options parameter is
// the object we defined above.
var req = https.request(options, function(res) {
  res.setEncoding('utf-8');

  var responseString = '';

  res.on('data', function(data) {
    responseString += data;
    //console.log(data);
  });

  res.on('end', function() {
    var resultObject = JSON.parse(responseString);
    console.dir(resultObject);
  });
});

req.on('error', function(e) {
  // TODO: handle error.
  console.log(e);
});

var product = {
  product:{
    id: productId, 
    variants: [
      {
        id:5991257025 //existing variant id
      },
      {
        id:5991257089 //existing variant id
      },
      {
        id:19762423495 //existing variant id
      },
      // new variant details
      {
        title:'v4', // new variant details
        option1: 'green',
        option2: "Honda", 
        option3: 'Civic'
      },{
        title:'v5',
        option1: 'pink',
        option2: "Honda", 
        option3: 'Civic'
      },{
        title:'v6',
        option1: 'yellow',
        option2: "Honda", 
        option3: 'Civic'
      },{
        title:'v7',
        option1: 'brown',
        option2: "Honda", 
        option3: 'Civic'
      }
      ]
    }

};

req.write(JSON.stringify(product));
req.end();