Handling Return Structure From DLL Library?

I’m working with a DLL Library file using soft declares. I’ve never tried to do it this way before I’ve always exposed the dll using active x but this is a C++ dll and I can’t get it to register for whatever reason. By digging through the C++ code I can see what each function parameter and return is. If the function returns an integer and requires a void param I have been able to get it working so I know I am on the right track. The main functions want struct and I haven’t been able to sort out the Xojo equivalent and how to do this part.

So for the first function:

[quote]/** Initialize the USB Relay Library
@returns: This function returns 0 on success and -1 on error.
*/
int USBRL_API usb_relay_init(void);[/quote]

So I wrote:

Soft Declare Function usb_relay_init Lib "E:\\Relay_Test\\USB_RELAY_DEVICE.dll" as Integer dim i as integer = 100 i = usb_relay_init TextArea1.Text = str(i)
…and it works! I get a 0 instead of 100 or -1.

This is where I get stuck…

[quote]/** Enumerate the USB Relay Devices.
@return Pointer to list of usb_relay_device_info
*/
pusb_relay_device_info_t USBRL_API usb_relay_device_enumerate(void);[/quote]

It wants to return the data as a structure. How do I get the return data into a structure and display it in my TextArea so I can use it to send the next command?

Soft Declare Function usb_relay_device_info Lib "E:\\Relay_Test\\USB_RELAY_DEVICE.dll" as //Structure //I tried Variant Xojo says I can't use an object here? dim v as variant v = usb_relay_device_info TextArea1.Text = v.StringValue

Thanks for any help…

did you try creating and passing a “structure”… This is the main reason these entity exists if for exactly what you are trying to do

of course you need to figure out what the structure needs to consist of…

[quote=305800:@Dave S]did you try creating and passing a “structure”… This is the main reason these entity exists if for exactly what you are trying to do

of course you need to figure out what the structure needs to consist of…[/quote]
Currently looking into this Dave. Trying to track down the params for a lot of other functions as well. Was hoping someone on here might have worked with something similar to this and could give me some advice. Thanks.

This is the method that returns the structure.

[quote]/** Enumerate the USB Relay Devices./
pusb_relay_device_info_t USBRL_API usb_relay_device_enumerate(void)
{
struct enumctx_s ectx;
int ret;
memset(&ectx, 0, sizeof(ectx));
ret = usbhidEnumDevices(USB_CFG_VENDOR_ID, USB_CFG_DEVICE_ID,
(void
)&ectx,
enumfunc);

return (pusb_relay_device_info_t)ectx.head;

}[/quote]

Any ideas how to alter this to work with it? I created a structure in xojo called ectx. Not sure how to add the declarations to match the above function though. :confused:

Soft Declare Function usb_relay_device_enumerate Lib "C:\\aaa\\Relay_Test\\USB_RELAY_DEVICE.dll" as ectx Dim e As ectx e = usb_relay_device_enumerate //?????????

There are two methods to accomplish this.
First, using pointer.

Soft Declare Function usb_relay_device_enumerate Lib "C:\\aaa\\Relay_Test\\USB_RELAY_DEVICE.dll" as ptr
Dim ectx as ptr
ectx = usb_relay_device_enumerate()

Second, using structure, but you need to declare the structure first

Structure pusb_relay_device_info
' structure's members
End Structure

Soft Declare Function usb_relay_device_enumerate Lib "C:\\aaa\\Relay_Test\\USB_RELAY_DEVICE.dll" as pusb_relay_device_info

dim ectx as pusb_relay_device_info
ectx = usb_relay_device_enumerate()

@Asis Patisahusiwa Thanks! I’ll give that a try. I just found the members of the structure too.

[quote]/** USB relay board info structure */
struct usb_relay_device_info
{
char *serial_number;
char device_path;
intptr_t /enum usb_relay_device_type/ type;
struct usb_relay_device_info
next;
};[/quote]

The only correct way would be to declare a structure and define your declare as returning that. I doubt specifying a pointer as the return type would even work.

@Joe Ranieri I had to do both. Declare a structure and use the pointer to get the data for the structure.

Soft Declare Function usb_relay_device_enumerate Lib cLibPath as Ptr

My structure:

serial_number as Ptr device_path as Ptr type as Integer next as Ptr

Thanks goes to @Tim Hare for the solution. :slight_smile:

Actually, using a pointer also work when calling external function. I don’t know if using a pointer in this case will work or not, but long time ago, I have done something similar to this. Using this code in one of my project, I can get the desired result.

soft Declare Function SHGetFileInfo Lib "shell32.dll" Alias "SHGetFileInfoA" (ByVal pszPath As CString, ByVal dwFileAttributes As Integer, psfi As Ptr, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As Integer

dim iFlag as Integer = SHGFI_TYPENAME Or SHGFI_SHELLICONSIZE Or SHGFI_SYSICONINDEX Or SHGFI_DISPLAYNAME Or SHGFI_EXETYPE Or SHGFI_LARGEICON or SHGFI_ICON
dim mbInfo as new MemoryBlock( 352 )
dim HFile as Integer

HIcon = SHGetFileInfo( FPath, 0,  mbInfo, mbInfo.Size, iFlag )

Name = mbInfo.CString( 12 )
Type = mbInfo.CString( 272 )
HIcon = mbInfo.Long(0)

I must admit that there is wrong in my code before, it should be

Dim ectx as MemoryBlock

[quote=307852:@Ryan Haynes]@Joe Ranieri I had to do both. Declare a structure and use the pointer to get the data for the structure.

Soft Declare Function usb_relay_device_enumerate Lib cLibPath as Ptr

My structure:

serial_number as Ptr device_path as Ptr type as Integer next as Ptr

Thanks goes to @Tim Hare for the solution. :)[/quote]
IMHO, you don’t need to use pointer for serial_number and device_path. char * in C is similar to CString in Xojo. So, you can use this instead,

serial_number as CString
device_path as CString
type as Integer
next as Ptr