Using C# classes in Xojo

No one?

Have you checked the values in retVal to make sure they arenā€™t pointers to your values and youā€™re not being sent a com.safearray? 24 bytes would be one 8 byte pointer to each value and a null 8 bytes to signify the end of the array of pointers. Just a guess as Iā€™ve not tested this personally but it might explain why the values change on every call.

Iā€™m being sent a COM.SafeArray. Iā€™m not sure whatā€™s inside the 24 bytes, itā€™s variable garbage to me. It can be anything or nothing at all.

If you zip up a demo vs project and xojo project Iā€™ll take a look.

Thanks, I will

There you are, thanks for your help
https://1drv.ms/u/s!ApYaAzYkAIgXqzt0xwoWpvtVCuqI?e=T1bZYv

Thanks Alessandro, but that is just three lines from above put in a xojo project.

Could you make a small simple VS project showing what youā€™re doing and the accompanying small Xojo project, zip them both up and link them?

There is nothing more than that at this point. Iā€™m just evaluating whether it is feasible and working. Itā€™s a simple call to a c# dll library. Just build the cs file with the giesecke reference in it and call it from the xojo project.

I was trying to get you to provide me with a working example of a simple VS and Xojo project so I didnā€™t have to read up on getting COM working in Xojo and getting the correct code and options in VS just to get to the point you were already at, never mind :slight_smile:

As I originally thought, the value returned from the Invoke is an address of a pointer to a COM.SafeArray so the Delegate needs to have ByRef added and changed to a Ptr

ConvertIntToRegisters_Func2(this As Ptr, intValue_Param As Integer, ByRef pRetVal_Param As Ptr)

Then inside ConvertIntToRegisters use the following code

[code]#if TargetWin32
If mThis = Nil Then Raise New NilObjectException
Dim func As New ConvertIntToRegisters_Func2(mThis.Ptr(0).Ptr(7 * COM.SIZEOF_PTR))
Dim resultCode As Integer
Dim Return_pRetVal_Param As New MemoryBlock(COM.SafeArray.Size)
Dim p As Ptr 'added this
'resultCode = func.Invoke(mThis, intValue_Param, Return_pRetVal_Param) 'removed as weā€™re going via another pointer
resultCode = func.Invoke(mThis, intValue_Param, p) 'used this version instead
Return_pRetVal_Param = p
If resultCode = 0 Then
Dim retVal As COM.SafeArray
retVal.StringValue(True) = Return_pRetVal_Param.StringValue(0, COM.SafeArray.Size)
Return retVal
Else // Throw Exception
Raise New COM.COMException(ā€œFailed on ConvertIntToRegistersā€, resultCode)
End If

#endif[/code]

The calling code then changes to

Dim o As New ClassLibrary2.XojoModbusClient Dim temp As COM.SafeArray = o.ConvertIntToRegisters(123) Dim content() As UInt8 = temp.ByteValue Dim data As Ptr = temp.pvData

Where data will contain your returned values.

This might be a bug with the auto code generation of the Xojo COM importer but as Iā€™ve not done COM in around 18 years Iā€™m not really in a position to say so with conviction.

1 Like

Iā€™ll give it a try later today or tomorrow. For the time being please accept my greatest thank you for you invaluable help.
Would you advice to report the bug and if yes, how can I do it?

Sorry, but it still doesnā€™t work. This is my ConvertIntToRegisters

[code]#if TargetWin32
If mThis = Nil Then Raise New NilObjectException
Dim func As New ConvertIntToRegisters_Func2(mThis.Ptr( 0 ).Ptr(15 * COM.SIZEOF_PTR ))
Dim resultCode As Integer
Dim Return_pRetVal_Param As New MemoryBlock( COM.SafeArray.Size )
Dim p As Ptr 'added this
'resultCode = func.Invoke(mThis, intValue_Param, Return_pRetVal_Param) 'removed as weā€™re going via another pointer
resultCode = func.Invoke(mThis, intValue_Param, p) 'used this version instead
If resultCode = 0 Then
Dim retVal As COM.SafeArray
retVal.StringValue(True) = Return_pRetVal_Param.StringValue(0, COM.SafeArray.Size)
Return retVal
Else // Throw Exception
Raise New COM.COMException(ā€œFailed on ConvertIntToRegistersā€, resultCode)
End If

#endif[/code]

Iā€™ve added and removed rows as per your suggestion, but please note the size of Ptr at row 3.
Changing it to 7 * COM.SIZEOF_PTR as per your example causes the function to crash at row 7 func.invoke.
Leaving it at 15 * COM.SIZEOF_PTR the execution ends nicely, but the return value is still a 24-items array, this time empty.

Iā€™m at a loss here.

Ah yes the 15 will need to remain the same as your dll has more calls than mine.

You missed this line, which puts the data into the memoryblock

Return_pRetVal_Param = p

place it on the line before the If resultCode = 0 Then

Iā€™ll see about adding the feedback ticket when I get a moment.

Thanks a lot, it now works as supposed, though much more work is necessaryā€¦ your help has been invaluable and I will forever be in debt. I will stop here for the time being, as I have to import a number of conversion routines, for which I canā€™t manually edit the interop functionā€¦I will wait for the ActiveX import to be debugged.
In the example above I used the following:

Dim o As New XojoEasyModbus.XojoModbusClient Dim temp As COM.SafeArray = o.ConvertIntToRegisters(123123) Dim content As UInt32 = temp.pvData.UInt32 Dim register(1) as UInt16 register(0) = content AND &H0000FFFF register(1) = BitWise.ShiftRight(content AND &HFFFF0000, 16, 32)

I realise it makes very little sense to split a 32bit integer into bytes, encoded into a 2x16bit array, get it back as 32bit consecutive bits with 4bytes memory pointer, and then mask and shift the 32bits, 16bits at a time.
This was sort of an exercise for testing Xojo capabilities.
i probably found a bug into UTF32 encoding, for which a separate thread will be opened.

Hi to everybody!
I start saying Iā€™m a newbie of Xojo (and so ignorant in using it)
I found this post because I would like to use a .net library in order to print labels on a thermal printer. Iā€™ve got an application named NiceLabel that has a SDK resident in a .net dll called SDK.NET.Interface.dll.
I would like to expose the com of this dll ans so Iā€™m trying to implement the example in this post, but there is a thing I canā€™t understand. How can I refer to the dll and the content of it?
For example the dll has class named PrintEngineFactory how can I insert it in the c# class I must create in order to expose it.
Many thanks

Eros

Hi Everyone,

I documented the way to create a C# DLL with Visual Studio 2019 on Windows 10 and have the functions work in Xojo 2020 r1.

Here is a link to the instructions:C# to Xojo Instructions

And here is a link to an Example Github project to try it out: C# DLL to Xojo Github Example

4 Likes

Still hoping that someone might be able to figure out how to do this under MacOS, since C# is now able to make X-Platform library files.