1 | initial version |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
using namespace cv;
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
return p;
}
int free_img(char *c)
{
if (nullptr != c)
{
delete[] c;
c = nullptr;
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
lib = ct.CDLL("void_dll.dll")
func = lib.alloc_img
func.restype = ct.c_char_p
bytes_array = func(ct.c_char_p(s.encode("utf-8")), width, height)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
2 | No.2 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
using namespace cv;
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
return p;
}
int free_img(char *c)
{
if (nullptr != c)
{
delete[] c;
c = nullptr;
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
lib = ct.CDLL("void_dll.dll")
func = lib.alloc_img
func.restype = ct.c_char_p
bytes_array = func(ct.c_char_p(s.encode("utf-8")), width, height)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
3 | No.3 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
using namespace cv;
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
return p;
}
Python code:
import ctypes as ct
import numpy as np
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
lib = ct.CDLL("void_dll.dll")
func = lib.alloc_img
func.restype = ct.c_char_p
bytes_array = func(ct.c_char_p(s.encode("utf-8")), width, height)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
4 | No.4 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
using namespace cv;
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height)
*height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
func alloc_img = lib.alloc_img
func.restype free_img = lib.free_img
alloc_img.restype = ct.c_char_p
bytes_array = func(ct.c_char_p(s.encode("utf-8")), alloc_img(ct.c_char_p(s.encode("utf-8")), width, height)
height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
5 | No.5 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
alloc_img.restype = ct.c_char_p
w = int(ct.c_long(width.contents).value)
h = int(ct.c_long(height.contents).value)
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (w, h)
#numpy_array = np.reshape(numpy_array, (width.contents, height.contents))
cv2.imshow("Frame", numpy_array)
cv2.waitKey(0)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
6 | No.6 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
alloc_img.restype = ct.c_char_p
w = int(ct.c_long(width.contents).value)
h = int(ct.c_long(height.contents).value)
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (w, h)
#numpy_array = np.reshape(numpy_array, (width.contents, height.contents))
(width.contents.value, height.contents.value)
cv2.imshow("Frame", numpy_array)
cv2.waitKey(0)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
7 | No.7 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cv2.imshow("Frame", numpy_array)
cv2.waitKey(0)
print(len(numpy_array))
print(numpy_array)
print(width.contents)
print(height.contents)
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
8 | No.8 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cv2.imshow("Frame", numpy_array)
cv2.waitKey(0)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
return 0;
}
9 | No.9 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}
10 | No.10 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <mutex>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
mutex rw_ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
rw_ids.lock();
ids[ids.size()] = p;
*image_id = ids.size() - 1;
rw_ids.unlock();
cout << "Created img id " << *image_id << endl;
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
rw_ids.lock();
if (nullptr != ci->second)
{
delete[] ci->second;
}
ids.erase(ci);
rw_ids.unlock();
return 0;
}
}
return 1;
}
}
return 0;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}
11 | No.11 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Input image:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <mutex>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
mutex rw_ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
rw_ids.lock();
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
rw_ids.lock();
ids[ids.size()] = p;
*image_id = ids.size() - 1;
rw_ids.unlock();
cout << "Created img id " << *image_id << endl;
rw_ids.unlock();
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
rw_ids.lock();
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
rw_ids.lock();
if (nullptr != ci->second)
delete[] ci->second;
ids.erase(ci);
rw_ids.unlock();
return 0;
}
}
rw_ids.unlock();
return 1;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}
12 | No.12 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a numpy array:
Input image:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <mutex>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
mutex rw_ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
rw_ids.lock();
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
rw_ids.unlock();
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
rw_ids.unlock();
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
rw_ids.lock();
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
delete[] ci->second;
ids.erase(ci);
rw_ids.unlock();
return 0;
}
}
rw_ids.unlock();
return 1;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}
13 | No.13 Revision |
I exported a DLL function that returns a char* array. The Python code calls the function and converts the bytes into a 2D numpy array:array, and back again to bytes:
Input image:
Windows code:
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <mutex>
using namespace std;
#define DLLEXPORT extern "C" __declspec(dllexport)
map<size_t, char*> ids;
mutex rw_ids;
DLLEXPORT int get_img_from_char_array(char *c, int *width, int *height)
{
Mat frame_content(*height, *width, CV_8UC1, c);
return 0;
}
DLLEXPORT char *alloc_img(const char *file_name, int *width, int *height, size_t *image_id)
{
rw_ids.lock();
Mat img = imread(file_name, IMREAD_GRAYSCALE);
if (img.empty())
{
*width = 0;
*height = 0;
rw_ids.unlock();
return nullptr;
}
*width = img.cols;
*height = img.rows;
size_t num_pixels = (*width)*(*height);
char *p = new char[num_pixels];
memcpy(p, img.data, num_pixels*sizeof(char));
ids[ids.size()] = p;
*image_id = ids.size() - 1;
cout << "Created img id " << *image_id << endl;
rw_ids.unlock();
return p;
}
DLLEXPORT int free_img(size_t *image_id)
{
rw_ids.lock();
for (map<size_t, char*>::const_iterator ci = ids.begin(); ci != ids.end(); ci++)
{
if (ci->first == *image_id)
{
cout << "Deleted img id " << *image_id << endl;
if (nullptr != ci->second)
delete[] ci->second;
ids.erase(ci);
rw_ids.unlock();
return 0;
}
}
rw_ids.unlock();
return 1;
}
Python code:
import ctypes as ct
import numpy as np
import cv2
ptr = ct.c_char_p()
s = "dove.png"
width = ct.pointer(ct.c_int())
height = ct.pointer(ct.c_int())
img_id = ct.pointer(ct.c_size_t())
lib = ct.CDLL("void_dll.dll")
alloc_img = lib.alloc_img
free_img = lib.free_img
get_img_from_char_array = lib.get_img_from_char_array
alloc_img.restype = ct.c_char_p
bytes_array = alloc_img(ct.c_char_p(s.encode("utf-8")), width, height, img_id)
numpy_array = np.frombuffer(bytes_array, dtype=np.uint8)
numpy_array.shape = (width.contents.value, height.contents.value)
cppbytes = numpy_array.tobytes()
get_img_from_char_array(cppbytes, width, height);
free_img(img_id)
I also have some extra code handy, which uses a void** pointer to allocate memory:
int func(void **ptr)
{
float *p = new float[50];
p[0] = 123.456;
*ptr = p;
return 0;
}
int main(void)
{
float *p = 0;
func(reinterpret_cast<void**>(&p));
cout << p[0] << endl;
delete[] p;
return 0;
}