2012-09-15 27 views
2

我正在尝试创建一个绑定到Linea Pro(这是他们在Apple Store,Lowes中使用的条形码扫描器)SDK。我使用David Sandor's绑定作为参考,但SDK已经更新了几次,因为2011年MonaTouch绑定到Linea Pro SDK

1月,我有最一切工作,除了playSound通话,这是习惯了,好了,戏Linea Pro设备上的声音。

从SDK .h文件具备呼叫如下:

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

我用INT []的NSArray,以及一个IntPtr为int []尝试,但似乎没有任何工作。

喜欢我的长相结合的最后不成功的迭代:

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

现在,这并不在所有的工作。另外请注意,我不知道如何处理错误:(NSError **)错误部分。

我对C缺乏一些严重的熟悉,所以任何帮助都将非常感激。

回答

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); 

这是最好的使用它调用你的内部结合公共helper方法来完成。您可以通过在其定义中添加[Internal]属性来制作PlaySound方法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,但应该是接近。

+0

你是个绅士和学者。明天早上我会试试这个。谢谢! – jeffrapp

+0

这是一个不行。 Mono balks在Marshal.WriteInt32(p [j ++],i)中,所以我将它改为'Marshal.WriteInt32(p,i,data [j ++])',仍然没有任何结果。也试图用GCHandle.Alloc获取IntPtr,没有任何结果。我尝试了xcode,'int sound [] = {2730,150,0,30,2730,2730}; int size = sizeof(sound); [linea playSound:100 beepData:sound length:size error:nil];',这是有效的。当调试器击中实际的PlaySound行时,应用程序输出显示' - [Linea playSound:beepData:length:error]:无法识别的选择器发送到实例0xa2e6b40',但没有发生真正的错误。 – jeffrapp

+0

我不知道你的原始数据格式是什么。看看其他'Marshal'方法(如'Copy')来复制你的数据。你也可以尝试将它绑定为一个'(int *)',并在你的帮助器方法中使用'unsafe fixed'。但没有硬件和上下文,我们所能做的只是猜测;-) – poupou

1

我有同样的麻烦。不过,上面的poupou提供的帮助足以让我走上正轨。我的linea pro设备现在提出了两声嘟嘟声,所以我认为我应该继续使用经过测试的代码。原谅任何样式messups,这是我的第一篇文章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; 

    }