1

I am working on a project for serial communications between Excel and an Arduino. The following is what I have in VBA for the reading of data from the Arduino which is where my problem lies.

Private Declare Function readFromSerialPort Lib "C:PathToDll.dll"(ByRef Buffer As String) As String

And in a looping function within my VBA I have the following which sets a cell value to a string which is my buffer.

BigData.Range("Buf").Value = "B                                            "

Another cell called dataWindow takes in Buf as an argument so it updates when this is called.

=readFromSerialPort(Buf)

And here is the C++ code on the other end in the DLL.

DLL_EXPORT BSTR WINAPI readFromSerialPort(LPBSTR bufferTemp) {
char errorMsg[] = "read failed";
char mbstring[MAX_STRING_SIZE];
BSTR wcstring = *bufferTemp;
int sLen = wcstombs(mbstring,wcstring,MAX_STRING_SIZE);

char charString[MAX_STRING_SIZE];
DWORD dwBytesRead = 0;

if (hSerial == INVALID_HANDLE_VALUE) {
    ErrorExit("ReadFile (port not open)");
    int wLen2 = mbstowcs(*bufferTemp,errorMsg,strlen(errorMsg));
    return *bufferTemp;
}

if(!ReadFile(hSerial, charString, sLen, &dwBytesRead, NULL)) {
    ErrorExit("ReadFile");
    int wLen2 = mbstowcs(*bufferTemp,errorMsg,strlen(errorMsg));
    return *bufferTemp;
}

int wLen2 = mbstowcs(*bufferTemp,charString,sLen);
return *bufferTemp;
}

The issue is that this works when called from a cell but not when I change it to declaring a string in VBA and calling the read from there.

  • Amusingly, I only just answered an old question about [the same problem](https://stackoverflow.com/a/44397832/11683) that I randomly stumbled upon. – GSerg Jun 06 '17 at 19:52
  • Also Amusingly, I had just found your posts and was wondering how to contact you to look at this post. Your post helped me to understand why they worked in the cell and not Dll but I suppose I am really asking that since I need a PVOID in the READFILE in the DLL, what is the easiest way to go about sending a string from VBA to the DLL so that I can change the string to be the information that I am receiving from the read and send it back. Should I use LPSTR to do this? – Alex Wardlow Jun 06 '17 at 20:36
  • Normally in VBA you declare the parameter `ByVal` `As String`, allocate the string before calling the function which will serve as the buffer (e.g. `s = String(0, 250)`), and use `LPSTR` on the C++ side, then it will work both ways. – GSerg Jun 06 '17 at 21:06
  • Thanks, it all woks now. – Alex Wardlow Jun 14 '17 at 15:19
  • GSerg, what if I wanted to pass an array of strings? and iterate through them in the DLL. I have posted a question on this titled : How to create an array of strings in VBA/Excel and send it to a C++ DLL so that it can be itterated through in the DLL. https://stackoverflow.com/questions/44637879/how-to-create-an-array-of-strings-in-vba-excel-and-send-it-to-a-c-dll-so-that – Alex Wardlow Jun 19 '17 at 19:01
  • Possible duplicate of [How to create an array of strings in VBA/Excel and send it to a C++ DLL so that it can be itterated through in the DLL](https://stackoverflow.com/questions/44637879/how-to-create-an-array-of-strings-in-vba-excel-and-send-it-to-a-c-dll-so-that) – Maciej Los Jun 20 '17 at 07:48

1 Answers1

0

GSerg has solved this issue. I had not understood that VBA automatically converts when passing as String, so that in the DLL I am not dealing with BSTRs but with ASCII char* or LPSTRs. Also that due to a bug in excel, calling functions from within a cell does not do this conversion.