Re: Re: Re: Net/Link: Problem with DLL (2)
- To: mathgroup at smc.vnet.net
- Subject: [mg49055] Re: [mg48918] Re: [mg48888] Re: Net/Link: Problem with DLL (2)
- From: Todd Gayley <tgayley at wolfram.com>
- Date: Tue, 29 Jun 2004 04:50:46 -0400 (EDT)
- References: <200406220931.FAA10242@smc.vnet.net>
- Sender: owner-wri-mathgroup at wolfram.com
At 01:51 AM 6/23/2004, Peter S Aptaker wrote: >After more reading and experimenting have now got something 'working' but >have some more questions: > >My Fortran DLLs are imported to Excel via VBA (see below). I have tried to >use the 'self documenting VB format for clarity but have >only beem able to preserve it precisely for Double scalars as: > >(1) Comment: To get Int32 I have replaced Long by long; I recall .Net has >longer >default Integers. Peter, To get Int32 you can use Int32, Integer or long (the latter being a Win32 C long). >(2) Comment: the OUT array "second from last arg" seems to only be >possible with Double[]. Yes, you need to declare "out" arrays as array types. This is also the case in C# and Visual Basic .NET. Your example VB declaration below uses 'ByRef res As Double' for this argument, but that won't work for VB. ByRef As Double will cause VB to pass the address of a double to the DLL, which is fine if the DLL function is going to write a single value into this address. But if the function expects to fill an array of values starting from that address it won't work. If the function writes a lot of data it might crash, and even if it doesn't you will just get back the first value of the array in the double slot. In VB .NET you would use 'ByVal res() As Double' for that argument, and in C# you would use 'double[]'. Either of those type specifications will work fine in DefineDLLFunction. Mathematica's DefineDLLFunction uses the same type specifications as you would need to use in Visual Basic .NET or C# for all arguments. >(3) Question: .. How can I make this a two dmensional array OUT. As you will >see I currently use a 1-D array and >Partition[]? Partitioning after the fact is the right way. To the DLL function, a multidimensional array is just a flat block of memory, so treat it that way on the .NET side and let Mathematica restore the partitioning later. >(4) Comment: the OUT "last arg" seems best as, out int ; as the manual >suggests. > >I guess this hybrid style is a mess but it was hard getting it working! As you say, the manual recommends using the C#-style "out int" declaration for arguments that are "the address of a single integer". You can use VB-style "ByRef x As Integer" if you like, but if you pass a ByRef parameter, .NET/Link doesn't know that the function isn't expecting a value of the right type going in, so you need to assign the symbol a throwaway value of the correct type to make the call: (* In C, foo is declared as void foo(int* x) and it writes an integer into x. *) DefineDLLFunction["foo", "somelib.dll", "Void", {"ByRef x As Integer"}] x = 42; (* Must assign garbage int value because ByRef was used in the declaration *) foo[x] (* x has a new integer value now *) If you declare the argument as "out int" instead, then .NET/Link doesn't care what value, if any, x has going into the function. VB .NET has no "out-only" notation, so it's often best to switch to C#-style notation for these types of arguments. In all other cases you can use pure VB.NET-style syntax if you prefer it. Todd Gayley Wolfram Research >Note that a real DLL would be needed to actually test this > >Mathematica >========= >In[407]:= >Clear[psaInductanceDLL, psaInductancedll]; >psaInductancedll = >DefineDLLFunction["psaMagIndMr2", "maths0000.dll", >"Void", {"ByVal m As long", "ByVal rp As Double", "Double[]", >"ByVal np As long", "ByVal rq As Double", "Double[]", >"ByVal nq As long", "ByVal gpp As long", "ByVal gpq As long", >"double[]", "out int"}] > >psaInductanceDLL[m_,rp_, zpl_List, rq_, zql_List, opt___Rule] := >Module[{ores}, >ores = MakeNETObject[Table[0.0, {np*nq}]]; >psaInductancedll[m, rp, zpl, np, rq, zql, nq, 4, 3, ores, status]; >res = Partition[NETObjectToExpression[ores] , {np}] >] >psaInductanceDLL is fast. > >My VBA (i.e. VB6) delaration is: >======================= >Declare Sub psaMagIndMr3 Lib "maths0000.dll" ( _ >ByVal m As Long, _ >ByVal rp As Double, ByRef zpl As Double, ByVal np As Long, _ >ByVal rq As Double, ByRef zql As Double, ByVal nq As Long, _ >ByVal gpp As Long, ByVal gpq As Long, _ >ByRef res As Double, ByRef status As Long) > > >Thanks > >Peter Aptaker > >----- Original Message ----- >From: "psa" <psa at laplacian.co.uk> To: mathgroup at smc.vnet.net >To: mathgroup at smc.vnet.net >Subject: [mg49055] [mg48918] [mg48888] Re: Net/Link: Problem with DLL (2) > >etc etc
- References:
- Re: Net/Link: Problem with DLL (2)
- From: "psa" <psa@laplacian.co.uk>
- Re: Net/Link: Problem with DLL (2)