Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

C API: Issue with getItemList and getItemListFilter

#1
I am having some trouble with getItemList and getItemListFilter in the C API. Here's a (hopefully) reproducible example.

Code:
// my_code.h (compiles to test.dll)
#include "robodk_api_c.h"
#include "robodk_api_c.c"

#ifdef _WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif

extern "C" EXPORT void testItemLists(int port, int expected_num_items);

Code:
// my_code.cpp (compiles to test.dll)
void testItemLists(int port, int expected_num_items) {

    char commandLineArgs[1024];
    RoboDK_t rdk = RoboDK_t();
    int actual_num_items = 0;
    char name[16];

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed with error: %d\n", iResult);
        return;
    }

    strcpy_s(commandLineArgs, "-NOSPLASH -SKIPMAINT");
    RoboDK_Connect(&rdk, "", port, commandLineArgs, "");

    Sleep(1000);

    if (!_RoboDK_connected(&rdk)) {
        fprintf(stderr, "Failed to start RoboDK API!!");
    }

    Item_t* all_items = (struct Item_t*)malloc(sizeof(Item_t) * expected_num_items);
    if (all_items == NULL){
        printf("Memory allocation failure.\n");
        exit(1);
    }

    printf("Testing getItemList.\n");
    RoboDK_getItemList(&rdk, all_items, expected_num_items, &actual_num_items);
    printf("\tactual_num_items = %d\n.", actual_num_items);
    printf("\texpected_num_items = %d\n", expected_num_items);
    printf("\tall item names:\n");
    for (int i=0; i<actual_num_items; i++){
        Item_Name(&all_items[i], name);
        printf("\t\t%s\n", name);
    }
    printf("\n");

    printf("Testing getItemListFilter, filtering for targets.\n");
    RoboDK_getItemListFilter(&rdk, ITEM_TYPE_TARGET, all_items, expected_num_items, &actual_num_items);
    printf("\tactual_num_items = %d\n.", actual_num_items);
    printf("\texpected_num_items = %d\n", expected_num_items);
    printf("\tall item names:\n");
    for (int i=0; i<actual_num_items; i++){
        Item_Name(&all_items[i], name);
        printf("\t\t%s\n", name);
    }
    printf("\n");

}

Code:
# test.py
from robodk import robolink
from cffi import FFI


rdk = robolink.Robolink()

ffi = FFI()
dll = ffi.dlopen('test.dll')
ffi.cdef('void testItemLists(int port, int expected_num_items);')

dll.testItemLists(rdk.PORT, len(rdk.ItemList()))

I run this code by manually opening the workstation I want to test with, then running `test.py` from the same folder that `test.dll` is in.

The expected behavior is to print information about the expected vs. actual number of items then print all item names. This will occur first to test getItemList then to test getItemListFilter.

The console output is not as-expected for my workstation. Here's the first few lines:
Code:
Testing getItemList.
RoboDK API ERROR: ╣α
        actual_num_items = 101
.       expected_num_items = 2405
        all item names:
                ░
                ♠
                ♠
                ♠
                ♠
                world
                x_rail_base
                x-rail
                Comau Smart5 NJ 220-2.7 Base
                Comau Smart5 NJ 220-2.7

Due to confidentiality, I unfortunately cannot share the workstation or console output on this forum. I emailed info@robodk.com.

The workstation I am using is fairly involved, with one external axis and many targets. I also tried this code on a smaller example workstation that just has a small number of nested reference frames and targets and a robot I pulled from the library with no external axes. In the case of the smaller example, the code worked as-expected.
#2
Hi,
Thanks to your submission, we have found bugs in the C API code.
They have already been fixed in this branch: https://github.com/RoboDK/RoboDK-API/tre...tatus-code
You can grab the files robodk_api_c.c and robodk_api_c.h from there.

At the same time you can get rid of the WSAStartup call.
The updated files make this call by themselves.


By the way, I can recommend you to increase the size of the variable name to a reasonably large value, for example 256 bytes:
Code:
void testItemLists(int port, int expected_num_items) {
    char commandLineArgs[1024];
    RoboDK_t rdk = RoboDK_t();
    int actual_num_items = 0;
    char name[256];
...
}
#3
Thank you, Dmitry!

I just pulled that branch and I noticed an issue. When I try to build with the new code, I get an error:
Code:
Error (active)    E0311    cannot overload functions distinguished by return type alone
 
This is because in `robodk_api_c.c`, the function `Item_Type` returns type `int`. However, in `robodk_api_c.h`, `Item_Type` returns type `enum eITEM_TYPE`.

It's possible that the issues I'm encountering are because I'm using a different compiler than you. (I'm using the MSVC one that comes with Visual Studio).

I modified the function and I was at least able to get it to compile. I'm pretty sure the type casting in here should work properly, but I didn't test it.
Code:
enum eITEM_TYPE Item_Type(const struct Item_t* inst) {
    _RoboDK_check_connection(inst->_RDK);
    _RoboDK_send_Line(inst->_RDK, "G_Item_Type");
    _RoboDK_send_Item(inst->_RDK, inst);
    _RoboDK_send_Item(inst->_RDK, inst);

    int itemtype = _RoboDK_recv_Int(inst->_RDK);
    _RoboDK_check_status(inst->_RDK);
    return (eITEM_TYPE)itemtype;
}
  




Users browsing this thread:
1 Guest(s)