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

Calling external library #21

Closed
DylanMMarques opened this issue Jul 31, 2023 · 4 comments
Closed

Calling external library #21

DylanMMarques opened this issue Jul 31, 2023 · 4 comments

Comments

@DylanMMarques
Copy link

Hello,

I am trying to use an external library called Kinesis from Thorlabs.

I can access the library but I run into an error because the software cannot find PresentationFramework

using DotNET

T"System.Reflection.Assembly".LoadFrom("C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.DeviceManagerCLI.dll")

T"Thorlabs.MotionControl.DeviceManagerCLI.DeviceManagerCLI, Thorlabs.MotionControl.DeviceManagerCLI".BuildDeviceList()
serial_number = collect(T"Thorlabs.MotionControl.DeviceManagerCLI.DeviceManagerCLI, Thorlabs.MotionControl.DeviceManagerCLI".GetDeviceList())

dcservoCLI = T"System.Reflection.Assembly".LoadFrom("C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.KCube.DCServoCLI.dll") [""]

@show serial_number # serial_number = ["27000577"]
kcube = dcservoCLI.GetType("Thorlabs.MotionControl.KCube.DCServoCLI.KCubeDCServo")
aux = convert(CLRObject, serial_number[1])
create = kcube.CreateKCubeDCServo(aux)

I get the following error:

ERROR: CLRException: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.IO.FileNotFoundException: Could not load file or assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified.
File name: 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
   at System.ModuleHandle.ResolveType(QCallModule module, Int32 typeToken, IntPtr* typeInstArgs, Int32 typeInstCount, IntPtr* methodInstArgs, Int32 methodInstCount, ObjectHandleOnStack type)
   at System.ModuleHandle.ResolveTypeHandle(Int32 typeToken, RuntimeTypeHandle[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
   at System.Reflection.RuntimeModule.ResolveType(Int32 metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments)
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(MetadataToken caCtorToken, MetadataImport& scope, RuntimeModule decoratedModule, MetadataToken decoratedToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1& derivedAttributes, RuntimeType& attributeType, IRuntimeMethodInfo& ctorWithParameters, Boolean& isVarArg)     
   at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1& attributes, RuntimeModule decoratedModule, Int32 decoratedMetadataToken, RuntimeType attributeFilterType, Boolean mustBeInheritable, ListBuilder`1 derivedAttributes)
   at System.Reflection.CustomAttribute.GetCustomAttributes(RuntimeModule decoratedModule, Int32 decoratedMetadataToken, Int32 pcaCount, RuntimeType attributeFilterType)
   at System.Attribute.GetCustomAttributes(Assembly element, Type attributeType, Boolean inherit)
   at System.Attribute.GetCustomAttribute(Assembly element, Type attributeType, Boolean inherit)
   at Thorlabs.MotionControl.PrivateInternal.Settings.DeviceConfigurationManager..ctor()
   at Thorlabs.MotionControl.PrivateInternal.Settings.DeviceConfigurationManager.get_Instance()
   at Thorlabs.MotionControl.DeviceManagerCLI.DeviceConfigurationManager..ctor()
   at Thorlabs.MotionControl.DeviceManagerCLI.DeviceConfigurationManager.get_Instance()
   at Thorlabs.MotionControl.KCube.DCServoCLI.KCubeDCServo.InitializeDevice(String serialNo)
   at Thorlabs.MotionControl.KCube.DCServoCLI.KCubeDCServo.CreateKCubeDCServo(String serialNo)
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   --- End of inner exception stack trace ---
   at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
   at CLRBridge.Meta.InvokeMember(IntPtr type, String name, BindingFlags bindingFlags, IntPtr binder, IntPtr target, IntPtr[] providedArgs, UInt32 argCount, IntPtr& exception)       
Stacktrace:
 [1] track_and_throw(exhandle::UInt64)
   @ DotNET.CLRBridge C:\Users\marquesd-admin\.julia\packages\DotNET\Rx490\src\CLRBridge.jl:46
 [2] InvokeMember(type::UInt64, name::String, bindingFlags::UInt32, binder::Int64, target::UInt64, providedArgs::Vector{UInt64})
   @ DotNET.CLRBridge C:\Users\marquesd-admin\.julia\packages\DotNET\Rx490\src\CLRBridge.jl:325
 [3] invokemember(flags::UInt32, type::CLRObject, this::CLRObject, name::Symbol, args::CLRObject)
   @ DotNET C:\Users\marquesd-admin\.julia\packages\DotNET\Rx490\src\marshalling.jl:83
 [4] invokemember
   @ C:\Users\marquesd-admin\.julia\packages\DotNET\Rx490\src\marshalling.jl:94 [inlined]
 [5] (::DotNET.PendingInvocation)(args::CLRObject)
   @ DotNET C:\Users\marquesd-admin\.julia\packages\DotNET\Rx490\src\operators.jl:19
 [6] top-level scope
   @ c:\Users\marquesd-admin\OneDrive - University of Birmingham\julia\dotNETKinesis.jl:13

Thanks

@azurefx
Copy link
Owner

azurefx commented Jul 31, 2023

If this library targets .NET Framework, it might not be compatible with .NET Core, but it's worth a shot.
Try loading the WPF assembly with absolute path first, then your library, like this:

julia> using DotNET

julia> T"System.Reflection.Assembly".LoadFrom(raw"C:\Windows\Microsoft.NET\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll") # Path to WPF PresentationFramework.dll on your computer
System.Reflection.RuntimeAssembly("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
julia> T"System.Reflection.Assembly".Load("PresentationFramework") # Now Assembly.Load works
System.Reflection.RuntimeAssembly("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")

@DylanMMarques
Copy link
Author

Thanks, it works after loading the PresentationFramework!

Quick additional question, how can I access enumerations?
For example, in python ,this works to access the values of the enumeration DeviceSettingsUseOptionType

import clr
clr.AddReference("C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.DeviceManagerCLI.dll")
from Thorlabs.MotionControl.DeviceManagerCLI import *
DeviceConfiguration.DeviceSettingsUseOptionType.UseFileSettings
DeviceConfiguration.DeviceSettingsUseOptionType.UseDeviceSettings
DeviceConfiguration.DeviceSettingsUseOptionType.UseConfiguredSettings

Thanks

@azurefx
Copy link
Owner

azurefx commented Aug 2, 2023

Enum types are accessed in the same way as other types, by specifying the fully qualified type name. And each enum value is a property of its type.

julia> T"System.DateTime".new(Int32(2003), Int32(5), Int32(1)).DayOfWeek.Equals(T"System.DayOfWeek".Thursday)
true

@DylanMMarques
Copy link
Author

Thanks! I managed to get access to the enumeration. However, the path is non intuitive relatively to the python example which matches the documentation:

T"System.Reflection.Assembly".LoadFrom("C:\\Program Files\\Thorlabs\\Kinesis\\Thorlabs.MotionControl.DeviceManagerCLI.dll")
options = T"Thorlabs.MotionControl.DeviceManagerCLI.DeviceSettingsSectionBase+SettingsUseOptionType, Thorlabs.MotionControl.DeviceManagerCLI"
options.UseFileSettings
# Thorlabs.MotionControl.DeviceManagerCLI.DeviceSettingsSectionBase+SettingsUseOptionType("UseFileSettings")

Thanks again for this package and the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants