EXPORTED_FN char* MyExtension_BufferPointer( void* _pBuffer, double _size)
{
// ...
}
That is the problem - the Windows Runner is still only 32bit.Now I have another problem
DLL has some opencv functions..
Gamemaker shows some errors when run
I put all DLL files from Opencv directories to my included files but nothing changed
LoadLibraryA failed with error code 193
LoadLibraryA failed with error code 193
LoadLibraryA failed with error code 193
LoadLibraryA failed with error code 193
LoadLibraryA failed with error code 193
LoadLibraryA failed with error code 193
Opencv libraries are 64bit and I must compile it as x64 in C++. Maybe this is the problem
/// @description Insert description here
// You can write your code in this editor
_ww=sprite_get_width(sprite0)
_hh=sprite_get_height(sprite0)
surf= surface_create(_ww,_hh)
surface_set_target(surf)
draw_clear_alpha(c_black,0)
draw_sprite(sprite0,0,0,0)
surface_reset_target();
buff=buffer_create(_ww*_hh*4,buffer_fixed,1)
buffer_get_surface(buff,surf,buffer_surface_copy,0,0)
DLLFunc = external_define("DLLGAMEMAKER.dll", "createImage", dll_cdecl, ty_real, 4, ty_real, ty_real, ty_real, ty_real);
var _a = external_call(DLLFunc, buffer_get_address(buff),_ww*_hh*4,_ww,_hh);
fn_export double createImage(char* buffer, char size,int width,int height) {
int buf;
(unsigned char *) buf;
memcpy(&buf,buffer, size);
cv::Mat img = cv::Mat(720,1280, CV_8UC4, buf);
cv::imshow("Original", img);
return 1;
}
fn_export double createImage(char* buffer, double size, double width, double height) {
// ...
}
DLLFunc = external_define("DLLGAMEMAKER.dll", "createImage", dll_cdecl, ty_real, 4, ty_string, ty_real, ty_real, ty_real);
int buf;
(unsigned char *) buf;
memcpy(&buf,buffer, size); // guess the size argument here should be either 4 or sizeof(buf)
_ww*_hh*4
, which seems correct to me. But on the DLL side you take it in as a char. And you use that same value for the memcpy.char*
corresponds to ty_string
, double
corresponds to ty_real
./// @description Insert description here
// You can write your code in this editor
_ww=sprite_get_width(sprite0)
_hh=sprite_get_height(sprite0)
surf= surface_create(_ww,_hh)
surface_set_target(surf)
draw_clear_alpha(c_black,0)
draw_sprite(sprite0,0,0,0)
surface_reset_target();
buff=buffer_create(_ww*_hh*4,buffer_fixed,1)
buffer_get_surface(buff,surf,buffer_surface_copy,0,0)
DLLFunc = external_define("DLLGAMEMAKER.dll", "createImage", dll_cdecl, ty_real, 3, ty_string,ty_real, ty_real);
external_call(DLLFunc,buffer_get_address(buff),_ww,_hh);
fn_export double createImage(char* _pBuffer, double width, double height) {
unsigned char* pBuffer = (unsigned char*)_pBuffer;
memcpy(&pBuffer,&_pBuffer, sizeof(pBuffer));
cv::Mat img = cv::Mat(height,width, CV_8UC4, pBuffer);
cv::imshow("Original", img);
return 1;
}
fn_export double createImage(char* address double width, double height) {
unsigned char* pBuffer = (unsigned char*)address;
memcpy(&pBuffer,&address, sizeof(pBuffer));
cv::Mat img = cv::Mat(height,width, CV_8UC4, pBuffer);
cv::imshow("Original", img);
memcpy(&address, &img.data[0], sizeof(address));
return 1;
}
You can certainly memcpy() from one to the other. The buffer you received from GML is a contiguous memory area of a fixed size, and you can treat it any way you want in the DLL (correctly or incorrectly as C/C++ allows you to...)Now the second part... Getting processed image to GM2 buffer back.
I was thinking like this: If I get data in C++ from GM2 buffer's address, after processing image memcpy again to original pointer address. But can't do this.
As you see pBuffer is my pointer for memcpy() and Mat is opencv image and image.data is array with image data.C++:fn_export double createImage(char* _pBuffer, double width, double height) { unsigned char* pBuffer = (unsigned char*)_pBuffer; memcpy(&pBuffer,&_pBuffer, sizeof(pBuffer)); cv::Mat img = cv::Mat(height,width, CV_8UC4, pBuffer); cv::imshow("Original", img); memcpy(&pBuffer, &img.data[0], sizeof(pBuffer)); return 1; }
I search google and GM forums but I can't find any example exactly.
There are some examples to get pointer address from C++ and buffer_seek from this address. This is the only way?
Or memcpy can copy from C++ to GM buffer?
width*height*sizeof(img.data[0])
under the assumption your buffer allocated in GML before calling the DLL function was made large enough to hold this amount of data (I don't know anything about this type of structure, nor how it correlates to your use in GML once the DLL call returns).fn_export double createImage(char* address, double width, double height) {
Mat img = Mat(height, width, CV_8UC4, address);
cv::imshow("Image from GM", img);
// same image copy to buffer back;
memcpy(&address[0], &img.data[0], width*height*4.);
return 1;
}