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\\GenICam.vin"));
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/GenICam.vin")));
// 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…