BTOUCH Error when binding unsafe code

brbbrb AUMember ✭✭
edited August 2015 in Xamarin.iOS

Hi,
I am trying to create a binding to an Objective-C class that takes a pointer to a float (an Objective-C array of floats to be precise). Sharpie generated the following:
// @interface SpectrumAnalyser : NSObject
[BaseType (typeof(NSObject))]
interface SpectrumAnalyser {
// -(void)getFrequencies:(float *)freqs;
[Export ("getFrequencies:")]
unsafe void GetFrequencies (float *freqs);
}

When I build the project I receive the following error:
BTOUCH: error BI1002: btouch: Unknown kind Single* freqs in method 'SpectrumAnalyserTestBinding.SpectrumAnalyser.GetFrequencies'

I tried changing the unsafe pointer to:
unsafe void GetFrequencies (ref float freqs);
but of course that won't let me pass an array of floats.

At its simplest - what I need to do is pass an array of floats to a method on a class written in Objective-C so that method can populate the array. Allocations and deallocation needs to be handled in my managed code.

Is there a work around for this?

Thanks

Bryon

Tagged:

Answers

  • brbbrb AUMember ✭✭
    edited August 2015

    Hi,

    Okay - I think I have solved this but I would appreciate a code review from someone.

    The Objective-C prototype is:

        -(void)getFrequencies:(float *)freqs;
    

    I have changed the AppDefinition.cs file to be:

        // -(void)getFrequencies:(float *)freqs;
        [Export ("getFrequencies:")]
        void GetFrequencies( ref float freqs );
    

    The managed c# code is now:

        float[] freqBuffer = new float[10];
        SpectrumAnalyser s = new SpectrumAnalyser ();
        s.GetFrequencies (ref freqBuffer[0]);
    

    My test harness in Objective-C is populating the buffer properly so it all appears to be fine. Are there any issues with this?

    Note that this does not change the fact that BTOUCH cannot handle signatures created by Sharpie. A float* or a float[] should be a pretty standard parameter type to unmanaged code...

    Thanks

  • BrendanMurphyBrendanMurphy USMember

    I'm having a similar issue. Is the getFrequencies function expecting a single float or an array of floats? Because I'm having a problem where an Objective-C function expects a pointer that will point to an array and I'm not sure how to pass that array into the C# function.

  • brbbrb AUMember ✭✭

    It is an array of floats. If you need to pass a pointer to a single-dimension array then the solution I have above works. The key thing to note is that you cannot use "unsafe" in the binding - or it won't compile. You need to pass a "ref."

    If you need to pass a pointer to a two-dimensional array then there is no solution (unless you pass a pointer to void and cast the crap out of it in unmanaged code).

    I have raised a defect for both the "unsafe" problem (even though their is a workaround) and the two-dimensional array problem. this.

  • brbbrb AUMember ✭✭

    Here is the response from the defect I raised:
    Comment 5 Rolf Bjarne Kvinge 2015-09-01 06:35:14 EDT
    Binding support is limited to the most frequently used types (we usually add
    support for more types when someone requests it though).

    In most cases this can be worked around using IntPtr and manually marshalling
    data as required.

  • softlionsoftlion FRBeta ✭✭✭

    How can you use IntPtr instead of float* or byte* ?

    Is there any sample ?

Sign In or Register to comment.