View Full Version : Again dotNet help needed - How to deal with structs and call this (new) method?
martinB 11-03-2009, 03:56 PM Here I go again, butting my head against the dotNet interface of 3ds Max.
There is this dotNet/C# math library (again), that offers a class for an iterative (BFGS) optimization method (http://www.alglib.net/optimization/lbfgs.php).
After compiling this to a dotNet assembly, I can create an "alglib.lbfgs" object just fine, and I also managed to create an "alglib.lbfgs+lbfgsstate" class value in MAXScript (note the + notation!) from the struct defined inside that object. But then I cannot do anything with that class, and when I try to call the main minlbfgs() method of the alglib.lbfgs class (which uses such a struct as parameter), I get (again) that dreaded error about not finding a matching function!
The C# source code of that class is
namespace alglib
{
public class lbfgs
{
public struct lbfgsstate
{
[...]
}
public static void minlbfgs(int n,
int m,
ref double[] x,
double epsg,
double epsf,
double epsx,
int maxits,
int flags,
ref lbfgsstate state)
{
[...]
FWIW, there also is example C# code for how to use that class at http://www.alglib.net/translator/ex/minlbfgs.html
Any comments & suggestions much appreciated!
Thanks!
-- MartinB
|
|
Gravey
11-04-2009, 04:25 AM
how are you creating the struct instance? the following code SHOULD work but i get a 'No constructor found which matched argument list: alglib.lbfgs+lbfgsstate' error trying to create the struct instance. dotnet.loadAssembly @"C:\lbfgs"
lbfgs = dotNetClass "alglib.lbfgs"
state = dotNetObject "alglib.lbfgs+lbfgsstate"
math = dotNetClass "AP.Math"
n = 3
m = 2
x = dotNetObject "System.Double[]" 3
x.SetValue (100 * math.RandomReal() - 50) 0
x.SetValue (100 * math.RandomReal() - 50) 1
x.SetValue (100 * math.RandomReal() - 50) 2
lbfgs.minlbfgs n m &x 0.0d0 0.0d0 0.0d0 0 &state
EDIT: edited the double array, copied the wrong thing...
EDIT 2: so i cheated and created a function in the assembly to return a new instance of the lbfgsstate struct... anyway now i'm at the same point as you are with a 'No method found which matched argument list' error... i'm guessing maxscript is having a hard time passing non standard data types by reference, ie. the lbfgsstate struct instance. At this point i'd suggest writing a small piece of C# to help you do what you need by avoiding passing the lbfgsstate struct instance by reference directly in mxs
martinB
11-04-2009, 04:00 PM
how are you creating the struct instance?
Yes, that seems to be the problem. I can create a dotNetClass value for the struct using dnc = dotNetClass "alglib.lbfgs+lbfgsstate" but I don't now how to create an instance of it.
Thanks for the suggestion about adding some C# code. Problem with that is that I then need to do this over and over again for each new class I want to use, and cannot directly update to a new version as it gets released anymore. Right now I'd like to understand what I am doing wrong with dotNet and/or MAXScript, or whether this is (another) bug?
Any other comments?
-- MartinB
biddle
11-04-2009, 08:53 PM
how are you creating the struct instance? the following code SHOULD work but i get a 'No constructor found which matched argument list: alglib.lbfgs+lbfgsstate' error trying to create the struct instance.
lbfgs.minlbfgs n m &x 0.0d0 0.0d0 0.0d0 0 &state
Looks like you are missing an argument.
lbfgs.minlbfgs takes 9, this code passes 8. There should be another int before the state.
...and Martin I don't know how to create a boxed version of a struct without resorting to come C#.
martinB
11-04-2009, 09:06 PM
...and Martin I don't know how to create a boxed version of a struct without resorting to come C#.
OK, thanks anyway!
-- MartinB
biddle
11-04-2009, 09:13 PM
...and Martin I don't know how to create a boxed version of a struct without resorting to some C#.Now I do!
Create 1 element array of them and then get the first element.
state = ((dotnetobject "alglib.lbfgs+lbfgsstate[]" 1).get 0)
martinB
11-04-2009, 09:31 PM
Now I do!
Create 1 element array of them and then get the first element.
state = ((dotnetobject "alglib.lbfgs+lbfgsstate[]" 1).get 0)
=8-)
Wow! What on earth made you try that?!
Is there any logic in that I can create an array of the struct, but not the struct itself?
Another dotNet mystery solved thanks to you,
thanks very much indeed!
-- MartinB
biddle
11-04-2009, 09:56 PM
It's one of those .NET performance gotchas that you always hear about: adding a struct to an array implicitly boxes it up so that can it be handled as an Object.
...only here it works in our favour!
martinB
11-04-2009, 10:06 PM
It's one of those .NET performance gotchas that you always hear about: adding a struct to an array implicitly boxes it up so that can it be handled as an Object.
...only here it works in our favour!
Jeeeeeez. I assume http://www.vistadb.net/blog/post/2008/08/15/Class-v-Struct.aspx talks about what you just said?
I would NEVER have found that solution....
Thank you very much indeed, again!
-- MartinB
Gravey
11-05-2009, 02:01 AM
Looks like you are missing an argument. ha you're right! no more errors when I put in the missing 0 before &state.
and great find with the struct-array-get-0 business!
martinB
11-16-2009, 10:39 AM
Small update to this problem:
Larry Minton from Autodesk pointed out to me that the problem in this case is that the struct does not declare a constructor. And while all structs have a parameterless default constructor, it does not show up using Reflection (which is the mechanism MAXScript uses to connect to dotNet). So it sounds like the cause of this problem is a dotNet limitation?
There is a workaround, though, by using the 'CreateInstance' method of the 'Activator' dotNet class, to create an instance of the struct. So, in my case, that would be
activator = dotNetClass "activator"
dnc = dotNetClass "alglib.lbfgs+lbfgsstate"
structinstance = activator.createInstance dnc
-- MartinB
biddle
11-16-2009, 06:45 PM
I'd never come across 'System.Activator'. What a find!
There are days when I am sure I'm learning the .NET framework in reverse. This is one of them.
Larry is The Man.
We live and learn.
CGTalk Moderation
11-16-2009, 06:45 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.
vBulletin v3.0.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.