Hi,
I am trying to get MATLAB to work with a DLL I wrote. The DLL allocates a buffer which remains static until a command is called to the DLL to release it.
I've been trying to work out a way to get the pointer to this buffer back to MATLAB and after a bit of research I think I have found a way. The trouble is if the buffer is allocated to be larger than ~200 or so bytes, MATLAB will crash and exit without any warning and I can't figure out why.
To simplify testing I made a much simpler stripped down DLL with just the buffer allocation stuff left over. Could someone have a look and see what I am doing wrong as I can't for the life of me work it out.
(p.s. I know it shouldn't be anything to do with I am using classes/C++ in my DLL as I have that working fine in another one, essentially all of the C++ is surrounded by C wrappers so MATLAB only ever calls C functions.)
I am using 64 bit MATLAB 2013a and 2014b, both do the same thing. The PC is Windows 7 x64 with 32GB RAM and Intel i7-5930 processor. I set the java heap size to the largest possible as well (I think it was ~16GB)
DLL TestingLib.cpp
// TestingDLL.cpp : Defines the exported functions for the DLL application.
//
#include "TestingLib.h"
#include <stdlib.h>
class TestingLib {
private:
PINT16 _buffer;
LONG _bufferLen;
public:
PINT16 getBuffer(){
return _buffer;
}
LONG getLength(){
return _bufferLen;
}
public:
TestingLib(LONG len) {
if (this) {
_buffer = (PINT16)malloc(len);
if (_buffer) {
for (SHORT i = 0; i < len; i++){
_buffer[i] = i;
}
_bufferLen = len;
}
else {
_bufferLen = -1; //FAIL!
}
}
}
~TestingLib(){
if (_buffer) {
free(_buffer);
}
}
};
typedef TestingLib *PTestingLib;
SYMBOL_DEF PVOID APIENTRY MakeBuffer(LONG length){
PTestingLib _handle = new TestingLib(length);
return (PVOID)_handle;
}
SYMBOL_DEF LONG APIENTRY GetBuffer(PVOID handle, PINT16 *buffer) {
if (handle) {
PTestingLib _handle = (PTestingLib)handle;
*buffer = _handle->getBuffer();
if (!*buffer) return -1;
return _handle->getLength();
}
return -1;
}
SYMBOL_DEF VOID APIENTRY ClearBuffer(PVOID handle) {
if (handle) {
delete (PTestingLib)handle;
}
}
DLL TestingLib.h (shared with MATLAB)
#pragma once
#include <windows.h>
#ifdef TESTINGLIB_EXPORTS
#define SYMBOL_DECLSPEC __declspec(dllexport)
#define SYMBOL_DEF __declspec(dllexport)
#else
#define SYMBOL_DECLSPEC __declspec(dllimport)
#define SYMBOL_DEF __declspec(dllimport)
#endif
#ifndef EXTERN_C
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C
#endif
#endif
EXTERN_C SYMBOL_DEF PVOID APIENTRY MakeBuffer(LONG length);
EXTERN_C SYMBOL_DEF LONG APIENTRY GetBuffer(PVOID handle, PINT16 *buffer);
EXTERN_C SYMBOL_DEF VOID APIENTRY ClearBuffer(PVOID handle);
MATLAB Script:
loadlibrary('TestingLib')
profile on
length = 2047;
handle = calllib('TestingLib','MakeBuffer',length);
bufferPtr = lib.pointer('int16Ptr');
calllib('TestingLib','GetBuffer',handle,bufferPtr);
setdatatype(bufferPtr,'int16Ptr',1,length);
bufferPtr.Value
profile viewer
calllib('TestingLib','ClearBuffer',handle);
bufferPtr = [];
handle = [];
----------------------
In the MATLAB script, when I set the length to <200 it works fine, but if I set it larger than that, MATLAB will just crash. I've attached the compiled library in case you want to try yourself.