12-28-2023 11:22 PM
I made this VI to subtract image2 from image1 using call library function. (I attached the VI).
What I intended was to read two images in cpp code, return the address (pointer), and use moveBlock function to transfer the pointer to 2d array of subtracted image but it did not work. I thought that the destination input of moveBlock can be any data that have the same type of the output I want. (2d array in this case) But it seems that it outputs exactly the same data as the input destination.
I'm asking if the wrapped cpp code is wrong or if I understand the moveBlock function wrong. I also want to know how to fix it.
Here is the cpp code. I built a dll from this code.
#include "rapid-af.h"
#include <chrono>
#include <opencv2/opencv.hpp>
using namespace cv;
extern "C" __declspec(dllexport) int main(unsigned char* imageIn1, unsigned char* imageIn2, int rows, int cols, int* resultAddress)
{
// Create Mat objects from the input image data
Mat inputImage1(rows, cols, CV_8UC1, imageIn1);
Mat inputImage2(rows, cols, CV_8UC1, imageIn2);
// Convert input images to double type
Mat doubleImage1, doubleImage2;
inputImage1.convertTo(doubleImage1, CV_64F);
inputImage2.convertTo(doubleImage2, CV_64F);
// Calculate the specified operation on the corresponding pixels
double result = ((doubleImage1.at<double>(rows, cols) - doubleImage2.at<double>(rows, cols)) + 65535) / 2.0;
// Convert the result to an integer using cvRound
int finalResult = cvRound(result);
// Allocate memory for the output image buffer
unsigned char* imageOut = new unsigned char[rows * cols];
// Store the address of the result in the provided pointer
*resultAddress = reinterpret_cast<int>(imageOut);
// Return 0 or another value indicating success
return *resultAddress;
}
Solved! Go to Solution.
12-29-2023 03:41 AM - edited 12-29-2023 03:41 AM
Hi, I advise you to refer to NI's 'call library node' example. It gives you a vast
number of different examples with code. Honestly, I dont understand your question. You write about reading in CPP and moveBlock, but yout code screenshot doesn't reflect that.
Maybe consider a simple minimal example, without unnecessary cast to double etc.
12-29-2023 08:17 AM - edited 12-29-2023 08:19 AM
You completely misunderstood basic memory management rules for standard C
You can NOT create random memory buffers in your C code and return its pointer to LabVIEW to let it use it. LabVIEW has absolutely no way to know what this pointer is. Your C code needs to provide the data in a way that LabVIEW can understand.
Also you can NOT replace the internal pointer in a LabVIEW handle by a randomly created memory pointer. The LabVIEW pointer “knows” to which handle it is assigned and also its size in a way that is unique to the LabVIEW memory manager. Your C array lacks this information and will confuse the LabVIEW memory manager completely.
You also leak the memory pointer in the LabVIEW data handle when replacing it with your own!
And your assumption that memory pointers are 4 bytes in size (or will fit in an int) will catastrophically fail if you ever try to port this to 64-bit.
Last but not least your C function has a 5-th parameter for the array pointer but your Call Library Node has not, but adding that to the Call Library Node is not your main problem.
Fixing this mess has a quick and dirty solution if you actually copy the resulting data back in one oft he passed in handles inside your C code.
01-02-2024 12:26 AM
Thank you for your specific explanation.
I truly understand that I had a wrong approach and that helped me to fix my problem quickly.
01-02-2024 12:28 AM
I solved the problem by using an example vi instead of making unnecessary double casts.
Thank you very much.