problem dealing with unicode in mexFunction

1 view (last 30 days)
I made a mexfunction to find the Hwnd of a window if its wiindow title matches a string. This was done by using a mexFunction "getWinHwnd.cc". E.g., After mex 'getWinHwnd', in matlab call getWinHwnd('untitled - notepad.exe') will get the hwnd number of a window: untitled - notepad.exe .
The problem is that if the window title has non-ascii unicode characters, the hwndNew = FindWindow(NULL,TEXT(windowNameBuf)) failed. I do not know where is the problem. Thanks in advance.
#include <windows.h>
#include "mex.h"
// The gateway routine
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// Input argument is a buffer to hold the window name
mxArray *Reply = NULL;
char *windowNameBuf;
mwSize buflen1;
const mxArray *string_array_ptr1 = prhs[0];
buflen1 = mxGetNumberOfElements(string_array_ptr1) + 1;
windowNameBuf = (char *) mxCalloc(buflen1, sizeof(char));
mxGetString(string_array_ptr1, windowNameBuf, buflen1);
// Call the C subroutine.
HWND hwndNew = FindWindow(NULL,TEXT(windowNameBuf));
Reply = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
*(uint64_T *) mxGetData(Reply) = (uint64_T) hwndNew;
plhs[0] = Reply;
}

Accepted Answer

raym
raym on 14 Aug 2018
Solved. Using mxArrayToString.
  10 Comments
raym
raym on 18 Aug 2018
Yes,I tried and found you are right. The doc is different from what I have seen.
>> version
ans =
9.0.0.341360 (R2016a)
>> mex mxArrayToString.c
Building with 'Microsoft Visual C++ 2010 (C)'.
MEX completed successfully.
>> c = repmat('a',1,100000000);
>> memory
Maximum possible array: 7256 MB (7.609e+09 bytes) *
Memory available for all arrays: 7256 MB (7.609e+09 bytes) *
Memory used by MATLAB: 1795 MB (1.882e+09 bytes)
Physical Memory (RAM): 8097 MB (8.490e+09 bytes)
* Limited by System Memory (physical + swap file) available.
>> for k=1:10; mxArrayToString(c); end
>> memory
Maximum possible array: 6396 MB (6.706e+09 bytes) *
Memory available for all arrays: 6396 MB (6.706e+09 bytes) *
Memory used by MATLAB: 2748 MB (2.881e+09 bytes)
Physical Memory (RAM): 8097 MB (8.490e+09 bytes)
* Limited by System Memory (physical + swap file) available.
>> memory
Maximum possible array: 6400 MB (6.711e+09 bytes) *
Memory available for all arrays: 6400 MB (6.711e+09 bytes) *
Memory used by MATLAB: 2748 MB (2.881e+09 bytes)
Physical Memory (RAM): 8097 MB (8.490e+09 bytes)
* Limited by System Memory (physical + swap file) available.
Below is the c code I adapted from other source. As I have never right c code before, could you help me on how to mexFree the mxArrayToString(string_array_ptr1)? Is there a need to state a variable for it in the beginning? Since the string is unicode from matlab, so the size of buffer for that string does not match the real size of unicode string, I cannot found a way to state it. Also, since the string_array_ptr1 is only a small string of dozens of bytes and called only a few times, will that memory leak cause a big broblem to the matlab? Thanks.
#include <windows.h>
#include "mex.h"
#include "matrix.h" //?
// The gateway routine
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// Input argument is a buffer to hold the window name
mxArray *Reply = NULL;
char *windowNameBuf;
mwSize buflen1;
const mxArray *string_array_ptr1 = prhs[0];
buflen1 = mxGetNumberOfElements(string_array_ptr1) + 1;
windowNameBuf = (char *) mxCalloc(buflen1, sizeof(char));
mxGetString(string_array_ptr1, windowNameBuf, buflen1); //?
// Call the C subroutine.
// mxGetString: only with characters represented in single-byte encoding schemes. For characters represented in multibyte encoding schemes, use the C function mxArrayToString.
// mxArrayToString is similar to mxGetString, except that:
// It does not require the length of the string as an input.
// It supports both multi-byte and single-byte encoded characters. On Windows&reg; and Linux&reg; platforms, the user locale setting specifies the default encoding.
// HWND hwndNew = FindWindow(NULL,TEXT(windowNameBuf));
HWND hwndNew = FindWindow(NULL,mxArrayToString(string_array_ptr1));
Reply = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL);
*(uint64_T *) mxGetData(Reply) = (uint64_T) hwndNew;
plhs[0] = Reply;
raym
raym on 18 Aug 2018
I made it this way, and mex was no problem:
char *str;
str = mxArrayToString(string_array_ptr1);
HWND hwndNew = FindWindow(NULL,str);
mxFree(str);

Sign in to comment.

More Answers (0)

Categories

Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!