2

I'm trying to create a binding to the Linea Pro (it's the barcode scanner they use in the Apple Stores, Lowes) SDK. I'm using David Sandor's bindings as a reference, but the SDK has been updated a few times since January of 2011.

I have most everything working, except for the playSound call, which is used to, well, play a sound on the Linea Pro device.

The .h file from the SDK has the call as follows:

-(BOOL)playSound:(int)volume beepData:(int *)data length:(int)length error:(NSError **)error;

I've tried using int[], NSArray, and an IntPtr to the int[], but nothing seems to work.

The last unsuccessful iteration of my binding looks like:

[Export ("playSound:beepData:length:")]
void PlaySound (int volume, NSArray data, int length);

Now, this doesn't work at all. Also note that I have no idea what to do with the error:(NSError **)error part, either.

I am lacking some serious familiarity with C, so any help would be extremely appreciated.

4

2 回答 2

1

NSArray除非Objective-C 代码使用,否则您不能使用NSArray,即生成器允许我们将一些ObjC 构造映射到.NET 类型(例如映射NSStringstring),但它不允许您重新定义ObjC 类型。

-(BOOL)playSound:(int)volume beepData:(int *)data length:(int)length error:(NSError **)error;

应该是这样的:

[Export ("playSound:beepData:length:error:")]
bool PlaySound (int volume, IntPtr data, int length, out NSError error);

您需要将您编组dataIntPtr.

IntPtr data = Marshal.AllocHGlobal (length);
Marshal.WriteInt32 (data1, 0);

然后释放它。

Marshal.FreeHGlobal (data);

最好使用调用内部绑定的公共辅助方法来完成。您可以通过在其定义中添加属性来创建该PlaySound方法。所以它变成:internal[Internal]

[Export ("playSound:beepData:length:error:")][Internal]
bool PlaySound (int volume, IntPtr data, int length, out NSError error);

并且您在绑定中包含以下代码(例如 API.cs):

bool PlaySound (int volume, int[] data)
{
    // I assume length is byte-based (check the docs)
    int length = data.Length * 4; 
    IntPtr p = Marshal.AllocHGlobal (length);
    int j = 0;
    for (int i=0; i < length; i+=4)
        Marshal.WriteInt32 (p [j++], i);
    NSError error;
    bool result = PlaySound (volume, p, length, out error);
    // free memory before throwing the exception (if any)
    Marshal.FreeHGlobal (data);
    if (error != null)
       throw new Exception (error.LocalizedDescription);
    return result;
}

注意:完全没有尝试过 :-) 我没有硬件、SDK 或文档。YMMV,但这应该很接近。

于 2012-09-15T23:52:39.680 回答
1

我遇到了同样的麻烦。然而,上面 poupou 提供的帮助足以让我走上正轨。我的 linea pro 设备现在在我要求它时会发出双哔声,所以我认为我应该跟进工作测试代码。原谅任何风格的混乱,这是我在stackoverflow上的第一篇文章......

这是我使用的导出定义。它与上面建议的相同,只是想验证它是否有效。

    [Export ("playSound:beepData:length:error:")]
    bool PlaySound (int volume, IntPtr data, int length, out NSError error);

从那里开始,我只需要学习足够多的 c# 就可以搞定编组。(我也是 c# 的新手)如您所见,这只是上面发布的内容的一个修补。非常感谢您为我指明了正确的方向!

    public void Beep()
    {
        int[] sound = {2730, 150, 0, 30, 2730, 150};
        PlaySound(100, sound);
    }

    public bool PlaySound(int volume, int[] data)
    {

        // length is byte-based
        int length = data.Length*4;
        IntPtr p = Marshal.AllocHGlobal(length);

        for (int i = 0; i < data.Length; i ++)
        {
            Marshal.WriteInt32(p, i*4, data[i]);
        }

        NSError error;
        bool result = dtDevice.PlaySound(volume, p, length, out error);

        // free memory before throwing the exception (if any)
        Marshal.FreeHGlobal(p);

        if (error != null)
            throw new Exception(error.LocalizedDescription);

        return result;

    }
于 2013-03-14T23:41:06.700 回答