Bug 12927 - TouchDB Query view throws MarshalDirectiveException
Summary: TouchDB Query view throws MarshalDirectiveException
Status: RESOLVED DUPLICATE of bug 4781
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 6.9.1.x
Hardware: PC Windows
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
Depends on:
Reported: 2013-06-27 16:49 UTC by Alexandre Pepin
Modified: 2013-07-04 10:31 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Alexandre Pepin 2013-06-27 16:49:58 UTC
I'm trying to query a view using TouchDB in C#. I used the binding between TouchDB and MonoTouch available here : https://github.com/mono/monotouch-bindings/tree/master/Couchbase

When the emit delegate method is called, I get a "System.Runtime.InteropServices.MarshalDirectiveException" saying "The type MonoTouch.Foundation.NSObject which is passed to unmanaged code must have a StructLayout attribute."

I found this bug report here : https://bugzilla.xamarin.com/show_bug.cgi?id=4781 that is similar to my problem but there isn't any updates since July 27, 2012.

Here's my test code :

CouchTouchDBServer server = new CouchTouchDBServer ();
CouchDatabase database = server.GetDatabase ("grocery-sync");
database.TracksChanges = true;

// Create a test view
design = database.DesignDocumentWithName ("grocery");
design.DefineView ("testView", (doc,emit) => {
    emit (doc, doc); // Crashes here
}, "1.0");

// Query the view
CouchQuery query = design.CereateQuery("testView");
RestOperation op = query.Start();
string response = op.ResponseBody.AsString;
Comment 1 Sebastien Pouliot 2013-07-04 09:07:28 UTC
I do not know* what the method declaration for `emit` looks like but such exceptions can occurs if you pass an `NSObject` to a p/invoke declaration instead of it's Handle (i.e. an IntPtr). IOW .NET does not know how to marshal this type (and it's not meant to be marshalled anyway).

* we can take a deeper look if you attach a self-contained test case that shows the issue.
Comment 2 Alexandre Pepin 2013-07-04 09:27:33 UTC
Here is a sample project that reproduces the problem : https://www.dropbox.com/s/azfml948th17axf/Sample%20Project.zip

Start by looking at the Objective-C projects named “MyObjectiveCProject”. In the interface “MyObjectiveCProject”, I have two block called “myBlock” and “myBlockToRecall”. The block “myBlock” receives “myBlockToRecall” parameter. I also have a method named “myTestMethod” that receives “myBlock” block. In the implementation of “myTestMethod” of the “MyObjectiveCProject” interface, I initialize a “myBlockToRecall” variable that only returns 5. With this variable, I called the “myBlock” block received in parameter.

In the binding project called “BindingProject”, I simply bound the “MyObjectiveCProject” compiled library. In the “ApiDefinition.cs”, I created the two delegates “myBlock” and “myBlockToRecall” and added the interface to bind “MyTestMethod”.

The test project named “TestProject” is a simple view Ipad project. I referenced the “BindingProject” so I can have access to my “MyTestMethod” method. In the method “ViewDidLoad” of the “TestProejctViewController.cs” class, I instantiate a “MyObjectiveCProject” class and I call the “myTestMethod” method with a delegate. When running the test project, it crashes inside my delegate when I call the delegate received from the Objective-C (line 42 : “return myBlockToRecall(NSObject.FromObject("123"));”). I have a “System.Runtime.InteropServices.MarshalDirectiveException” saying “Type MonoTouche.Foundation.NSObject which is passed to unmanaged code must have a StructLayout attrivute.”
Comment 3 Sebastien Pouliot 2013-07-04 10:03:34 UTC
   public delegate int myBlockToRecall(NSObject myObject);

   public delegate int myBlock(myBlockToRecall myBlockToRecall);

You're using a delegate inside a delegate to try to call a block from a block. This is identical to bug #4781.

It seems our bindings expose the same issue (unless I'm missing an update in some branch) and the sample does not use that part of the bindings.

*** This bug has been marked as a duplicate of bug 4781 ***
Comment 4 Alexandre Pepin 2013-07-04 10:31:57 UTC
So is there any updates for the bug 4781?