0

Issue

I'm attempting to print out an error buffer on a WINAPI GUI. As writtin, my code attempts to read or write memory which has not been allocated causing an error to be thrown.

There must be some way to elegantly convert from a character array to a LPCTSTR. What is that way?

Code

char        errBuff[2048] = { '\0' };

and later

Error:
            if (DAQmxFailed(error))
                DAQmxGetExtendedErrorInfo(errBuff, 2048);
            if (taskHandle1 != 0) {
                /*********************************************/
                // DAQmx Stop Code
                /*********************************************/
                DAQmxStopTask(taskHandle1);
                DAQmxClearTask(taskHandle1);

            }

            if (DAQmxFailed(error)) //TODO: Test this
                printf("DAQmx Error: %s\n", errBuff);
            printf("End of program, press Enter key to quit\n");
            AppendText(hOut, L"NIDAQmx Error\n");
            wchar_t myErrBuff = (wchar_t)errBuff;
            AppendText(hOut, (LPCTSTR) myErrBuff);
            break;

And the contents of AppendText


void AppendText(HWND hEditWnd, LPCTSTR Text) {
    int idx = GetWindowTextLength(hEditWnd);
    SendMessageW(hEditWnd, EM_SETSEL, (WPARAM)idx, (LPARAM)idx);
    SendMessageW(hEditWnd, EM_REPLACESEL, 0, (LPARAM)Text);
}

  • 1
    Can you describe what this line should be doing? `wchar_t myErrBuff = (wchar_t)errBuff;` – Drew Dormann Sep 14 '21 at 16:17
  • 2
    It seems you're looking for [`MultiByteToWideChar`](https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar). – dialer Sep 14 '21 at 16:20
  • Why don't you define myErrBuff as wchar_t right at the beginning? Microsoft uses wchar_t as default for most of its api. – moi Sep 14 '21 at 16:20
  • @moi `DAQmxGetExtendedErrorInfo` writes to a `char[]` - but perhaps OP could write an `AppendTextA` function instead of `AppendText(W)` – Ted Lyngmo Sep 14 '21 at 16:22
  • In that case - MultiByteToWideChar or look at std::format. fmtlib accepts both char and wchar for some operations. – moi Sep 14 '21 at 16:26
  • `wchar_t myErrBuff = (wchar_t)errBuff;` is my attempting to cast the char[] to a wide character array which is what is accepted by the WINAPI text output features. For example CreateWindowW – Mark Musil Sep 15 '21 at 11:28

1 Answers1

1

Since DAQmxGetExtendedErrorInfo writes the error message to a char[] I'd add a AppendTextA function to send those those strings directly to the WinAPI, without conversion.

void AppendTextA(HWND hEditWnd, LPCSTR Text) {
    int idx = GetWindowTextLength(hEditWnd);
    SendMessageA(hEditWnd, EM_SETSEL, (WPARAM)idx, (LPARAM)idx);
    SendMessageA(hEditWnd, EM_REPLACESEL, 0, (LPARAM)Text);
}

And when the error is supposed to be sent:

if (DAQmxFailed(error))
    printf("DAQmx Error: %s\n", errBuff);
printf("End of program, press Enter key to quit\n");
AppendTextA(hOut, "NIDAQmx Error\n");
AppendTextA(hOut, errBuff);
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • This is assuming that the code page used by the DAQmx functions is equal to `CP_ACP` in the calling process. Which is *probably* true given NI's crappy stone age software, but is not generally a safe assumption. Unless you looked it up in the manual I suppose. – dialer Sep 14 '21 at 16:35
  • @dialer True - and I did _not_ check the documenttion for NI's software :-) – Ted Lyngmo Sep 14 '21 at 16:38
  • @dialer I searched the NI docs for _unicode_, _utf_, _locale_ etc but couldn't find _any_ information. Assuming `"C"` ... – Ted Lyngmo Sep 14 '21 at 16:45
  • @dia It also works irrespective of the calling thread's code page in case of ASCII. Which, being stone age software, isn't all that unreasonable an assumption. – IInspectable Sep 14 '21 at 16:49
  • @IInspectable NI's error messages are localized iirc. But given there's no hint to UTF-8 in the documentation, just assuming it's compatible with the ANSI Win32 functions is probably the next best guess `/shrug`. – dialer Sep 14 '21 at 16:53
  • @dialer I agree that this answer is possibly taking a shortcut that may not survive in the long run. I liked your `MultiByteToWideChar` suggestion better. If you add an answer, you'd get my vote. – Ted Lyngmo Sep 14 '21 at 16:58
  • 1
    @ted The answer is totally fine, `MultiByteToWideChar` has the exact same issue in that you need to know the correct code page for the conversion. The sole purpose of my comment was to make future readers aware that this isn't universally applicable, especially since most modern (and sane) APIs use UTF-8 for `char` strings. Assuming it's CP_ACP is still probably the best guess for this specific DAQmx API. – dialer Sep 14 '21 at 17:04
  • @dialer Cheers! I always get a bit nervous when conversions between _something_ and _something_ else and windows code pages comes up :-) – Ted Lyngmo Sep 14 '21 at 17:06
  • @TedLyngmo Thanks for your thoughtful answer. I'm not getting results using your suggestions but am seeing that this may be an issue with code page used by NIDAQmx as described by dialer. – Mark Musil Sep 15 '21 at 11:26
  • @MusilMark Yes, that's possible. I didn't find any information about this in the NIDAQmx doc but ... who knows :) Do you get the proper output when you do `printf("DAQmx Error: %s\n", errBuff);`? Does the printed string contain non-ASCII characters? – Ted Lyngmo Sep 15 '21 at 12:40
  • @TedLyngmo I set up a console allocation and no I am not able to see the output of that line but for some reason I can see the output of the following line `printf("End of program, press Enter key to quit\n")`. Thoughts? – Mark Musil Sep 15 '21 at 18:05
  • I got it working using these lines `DAQmxGetExtendedErrorInfo(errBuff, 2048); printf("DAQmx Error: %s\n", errBuff); printf("End of program, press Enter key to quit\n");` which also prints the error buffer at the GUI – Mark Musil Sep 15 '21 at 18:12
  • @MusilMark Ok, Does it show any non-ASCII characters in `errBuff`? You could save it to a file and check that all `char`s are 0-127 (decimal) – Ted Lyngmo Sep 15 '21 at 18:14