GenApi StringNode Value Access

Hello together,

I want to access the values of StringNodes that are located in the Device Nodemap of a camera.
Therefore my approach is as follows:

    //Path to VIN
    Cvb::String path(CVB_LIT("%CVB%Drivers\\"));
    path = Cvb::ExpandPath(path);
    //Open Device
    device = Cvb::DeviceFactory::Open(path);
    //Get NodeMap
    Cvb::String nodeMapName(CVB_LIT("Device"));
    auto nodeMap = device->NodeMap(nodeMapName);
    // A) Access value using Cvb::StringNode
    Cvb::StringNode vendorNameNode =  nodeMap->Node(Cvb::String(CVB_LIT("Std::DeviceVendorName"))).get()

    // B) Acces value using C-style Api
    NODEMAP nodeMapCApi = nodeMap->Handle();
    NODE deviceVendorNameNode;    
    cvbres_t restulT = NMGetNode(nodeMapCApi, "DeviceVendorName", deviceVendorNameNode);

    size_t strSize; 
    NGetAsString(deviceVendorNameNode, NULL, strSize);
    char* tmpStr= (char *)malloc(strSize * sizeof(char*));

    NGetAsString(deviceVendorNameNode, tmpStr, strSize);

The access of the value using the C-Style Api (B) after receiving the handle from Cvb::NodeMap works fine but the access of the value using Cvb::StringNode (A) leads to an empty value.
Is it programmatically correct to pass the result of a shared_ptr*<Cvb::GenApi::Node>::get() to a Cvb::StringNode instance or am I wrong here?

Let me rewrite your spinet line and hopefully clear some misconceptions.

// CVB_LIT is only usfull if your code must compile with wide strings and 
// Unicode (usually on Windows and Linux), So it only makes sense 
// together  with a compatible path notation (lower-case and forward slash)! 
auto device = Cvb::Device::Open(Cvb::ExpandPath(CVB_LIT("%CVB%/drivers/")));

// You can always pass your literals directly, if not it is a bug on our side! 
auto deviceNodeMap = device->NodeMap(CVB_LIT("Device"));

// Your A) will not compile as types do not match.
// If you need the a node's value you should provide the type alongside 
// NodeMap::Node, to automatically  cast the node to the wanted type.
// Without casting you will only get the base node type.  
auto stringNode = deviceNodeMap->Node<Cvb::StringNode>(CVB_LIT(DeviceVendorName));

// Get the actual value. 
// Note: it is not recommended to mix classic C-API and the object oriented wrappers.
// The only reason to do so, is because the wrappers are still missing some features! 
auto value = stringNode->Value();

In addition to what @Andreas wrote: It is generally not a good idea to mix the next-gen APIs with the classic API. In principle it’ll work, but one would have to be aware of the ways in which the next-gen APIs handle object ownership, otherwise it’ll be easy to mess things up pretty badly.

Generally speaking: Whenever you have a feeling that there might be something missing in the next-gen API, then point it out to us rather than looking for a workaround that might be very frustrating to implement and/or debug.

Just to clarify: Mixing the CVB.Net, CVB++ or CVBpy APIs with the C-API of tools that are not (yet) covered by these new APIs by means of passing the handles of the underlying objects to the C functions is generally ok. But mixing the C-API with the CVB.Net, CVB++ or CVBpy API where the same functionality is covered (e. g. by handling nodemap access partly through the CVB++ classes and partly through the header iCVGenApi.h) should be approached with extreme caution…

1 Like