Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find and Call function in dll #9

Closed
gitboy16 opened this issue May 26, 2021 · 9 comments
Closed

Find and Call function in dll #9

gitboy16 opened this issue May 26, 2021 · 9 comments

Comments

@gitboy16
Copy link

Hi,
Thank you for the package.
I manage to assemblies from a dll following the example in the readme file. Would you be able to tell me how I can list the functions in that dll and call it?
Thank you
Best regards

@azurefx
Copy link
Owner

azurefx commented Aug 23, 2021

You can get whatever you want through reflection API.

julia> asm = T"System.Reflection.Assembly".LoadFrom(raw"C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.18\System.Windows.Forms.dll")
System.Reflection.RuntimeAssembly("System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")

julia> asm.ExportedTypes |> collect
1021-element Array{CLRObject,1}:
 System.Drawing.Design.IPropertyValueUIService
 System.Drawing.Design.PaintValueEventArgs
 System.Drawing.Design.PropertyValueUIHandler
 System.Drawing.Design.PropertyValueUIItem
 System.Drawing.Design.PropertyValueUIItemInvokeHandler
 System.Drawing.Design.UITypeEditor
 System.Drawing.Design.UITypeEditorEditStyle
 
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+SmallCaptionSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+FrameLeftSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+SmallFrameLeftSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+FrameRightSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+SmallFrameRightSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+FrameBottomSizingTemplate
 System.Windows.Forms.VisualStyles.VisualStyleElement+Window+SmallFrameBottomSizingTemplate

julia> Form = T"System.Windows.Forms.Form, System.Windows.Forms"
System.Windows.Forms.Form

julia> Form.GetMembers() |> collect
720-element Array{CLRObject,1}:
 System.Reflection.RuntimeMethodInfo("Void SetDesktopBounds(Int32, Int32, Int32, Int32)")
 System.Reflection.RuntimeMethodInfo("Void SetDesktopLocation(Int32, Int32)")
 System.Reflection.RuntimeMethodInfo("Void Show(System.Windows.Forms.IWin32Window)")
 System.Reflection.RuntimeMethodInfo("System.Windows.Forms.DialogResult ShowDialog()")
 System.Reflection.RuntimeMethodInfo("System.Windows.Forms.DialogResult ShowDialog(System.Windows.Forms.IWin32Window)")
 System.Reflection.RuntimeMethodInfo("System.String ToString()")
 System.Reflection.RuntimeMethodInfo("Boolean ValidateChildren()")
 
 System.Reflection.RuntimeEventInfo("System.EventHandler SystemColorsChanged")
 System.Reflection.RuntimeEventInfo("System.ComponentModel.CancelEventHandler Validating")
 System.Reflection.RuntimeEventInfo("System.EventHandler Validated")
 System.Reflection.RuntimeEventInfo("System.EventHandler ParentChanged")
 System.Reflection.RuntimeEventInfo("System.EventHandler ImeModeChanged")
 System.Reflection.RuntimeEventInfo("System.EventHandler Disposed")
 System.Windows.Forms.Form+ControlCollection

See also: #11

@gitboy16
Copy link
Author

gitboy16 commented Oct 22, 2021

Thank you. I manage to find the function I wanted. When I call it, it returns me the following:

System.Object[,,]("System.Object[,,]")

I am not sure what that is.
Is there a way to read the output in a Julia object ...like matrix, vector or anything else?

Also is there a way to create such an object from Julia and pass it to a function in the dll.

@azurefx
Copy link
Owner

azurefx commented Oct 27, 2021

I am not sure what that is.

It is just a multidimensional array with a rank of 3. All array types are subtypes of System.Array.

julia> isassignable(T"System.Array", T"System.Int32[,,]")
true

julia> isassignable(T"System.Int32[,,]", T"System.Array")
false

Is there a way to read the output in a Julia object ...like matrix, vector or anything else?

We have collect function that converts .NET arrays to Julia arrays.

However, n-d arrays are not fully supported now, so they become 1-d arrays when you collect them. You can usereshape function to recover dimension sizes.

public static int[,,] Get3DArray() {
  return new int[2, 2, 2] {
    {{1, 2}, {3, 4}},
    {{5, 6}, {7, 8}}
  };
}
julia> a = YourClass.Get3DArray()
System.Int32[,,]("System.Int32[,,]")

julia> collect(a)
8-element Array{Int32,1}:
 1
 2
 3
 4
 5
 6
 7
 8

julia> reshape(ans, 2, 2, 2)
2×2×2 Array{Int32,3}:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

Other useful methods for .NET arrays:

julia> clrtypeof(a) # returns a CLR Type object
System.Int32[,,]

julia> clreltype(a) # returns the element type of a CLR array
System.Int32

julia> eltype(a) # returns the element type in Julia, if the array is collected
Int32

julia> a.GetValue(Int32[1,0,1]) # to access the n-d array without collecting
6

Also is there a way to create such an object from Julia and pass it to a function in the dll.

Yes, just pass the object to the function.

julia> b = reshape(1:8, 2, 2, 2)
2×2×2 reshape(::UnitRange{Int64}, 2, 2, 2) with eltype Int64:
[:, :, 1] =
 1  3
 2  4

[:, :, 2] =
 5  7
 6  8

julia> Console.WriteLine(b);
System.Int64[,,]

If you want an uninitialized array, there is a convenient function:

julia> DotNET.arrayof(T"System.Int32", (2, 2, 2))
System.Int32[,,]("System.Int32[,,]")

@gitboy16
Copy link
Author

gitboy16 commented Oct 28, 2021

Thank you. The above is very useful.
Let's say I have the following:

julia> data = DotNET.arrayof(T"System.Object",(2,2,2))
System.Object[,,]("System.Object[,,]")

julia> data |> collect
8-element Vector{CLRObject}:
null
null
null
null
null
null
null
null

How do I actually add values in that vector?
(I want the array to be initilised with values)

Not sure if it can help but when I call some function in the dll I get something like that:

julia> Form.getIDs("")
System.Object[,,]("System.Object[,,]")

julia> Form.getIDs("") |> collect
4-element Vector{CLRObject}:
System.String("bi_id")
System.String("name")
System.String("internal")
System.String("external")

Thank you in advance.

@azurefx
Copy link
Owner

azurefx commented Oct 28, 2021

arraystore can do the job, which I forgot to mention.

julia> data = DotNET.arrayof(T"System.Object", (2, 2, 2))
System.Object[,,]("System.Object[,,]")

julia> DotNET.arraystore(data, (0, 0, 0), "bi_id")
null

julia> DotNET.arrayload(data, (0, 0, 0))
"bi_id"

julia> collect(data)
8-element Array{CLRObject,1}:
 System.String("bi_id")
 null
 null
 null
 null
 null
 null
 null

Note: In case you have a CLRObject that represents a primitive type (aka "boxed"), you can call unbox to retrieve the underlying data:

julia> collect(data)[1]
System.String("bi_id")

julia> DotNET.unbox(ans)
"bi_id"

Since Julia does not distinguish between boxed and unboxed types, values returned from .NET functions are automatically unboxed. So far, the collect function is not recursive, and I wonder if this should be changed in the future...

@gitboy16
Copy link
Author

You are a star. Thank you very much. I think it is worth saving the above in a manual or wiki as it can be useful to others. Feel free to close this "issue".

@gitboy16
Copy link
Author

gitboy16 commented Feb 8, 2022

Hi, I hope you are well. I was wondering how hard would it be to support n-d arrays so it is possible know what is the real dimension of the arrays returned? Right now I have to guess it which is a bit of an issue. Thank you.

@azurefx
Copy link
Owner

azurefx commented Mar 1, 2022

Supported in v0.2.0, README updated.

@gitboy16
Copy link
Author

gitboy16 commented Mar 2, 2022

You are the best. Thank you.

@gitboy16 gitboy16 closed this as completed Mar 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants