I figured it out. I'm posting this in case the one other person in the universe that wants to do this can find it useful.
First, an ugly hack to get mex to find the VISA framework: I made a symbolic link in the directory that I am building the mex file in:
ln -s /Library/Frameworks/VISA.framework/VISA libVISA.dylib
Afterwards, I modified my build script:
#!/bin/sh
MATLAB=/Applications/MATLAB_R2018b.app
MEX=$MATLAB/bin/maci64/mex
MEX_FLAGS="-v -largeArrayDims"
VISA_HEADERS=/Library/Frameworks/VISA.framework/Headers
# VISA_LIBRARIES=/Library/Frameworks/VISA.framework
$MEX $MEX_FLAGS -I$VISA_HEADERS -L. -lVISA visa_enumerate.c
Then, fixed some of the issues in the test code:
#include "mex.h"
#include "matrix.h"
#include "visa.h"
#include <string.h>
#include "ctype.h"
#define BUFFER_SIZE 256
mxArray* enumerateInstruments()
{
ViSession defaultRM;
ViSession instr;
ViStatus status;
ViChar buffer[BUFFER_SIZE];
ViUInt32 device_count;
ViFindList flist;
viOpenDefaultRM(&defaultRM);
viFindRsrc(defaultRM, (ViString)"?*INSTR", &flist, &device_count, buffer);
char* fieldnames[3]= {"ResourceName", "Alias", "Identification"};
mxArray *deviceList = mxCreateStructMatrix(device_count, 1, 3, (const char**)fieldnames);
while (device_count--)
{
status = viOpen(defaultRM, buffer, VI_NULL, 3000, &instr);
if (status == VI_SUCCESS)
{
status = viGetAttribute(instr, VI_ATTR_RSRC_NAME, buffer);
if (status == VI_SUCCESS)
{
mxSetField(deviceList, device_count, "ResourceName", mxCreateString(buffer));
}
ViUInt16 intfType;
ViUInt16 intfNumber;
ViChar alias[BUFFER_SIZE];
status = viParseRsrcEx(defaultRM, buffer, &intfType, &intfNumber, VI_NULL, VI_NULL, alias);
if (status == VI_SUCCESS)
{
mxSetField(deviceList, device_count, "Alias", mxCreateString(alias));
}
status = viQueryf(instr, (ViString)"*IDN?\n", (ViString)"%t", buffer);
if (status == VI_SUCCESS)
{
// Remove trailing whitespace.
char *end = buffer + strlen(buffer) - 1;
while (end > buffer && isspace((unsigned char) *end))
{
*end = '\0';
end--;
}
mxSetField(deviceList, device_count, "Identification", mxCreateString(buffer));
}
}
viClose(instr);
viFindNext(flist, buffer);
}
viClose(flist);
viClose(defaultRM);
return deviceList;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *data = enumerateInstruments();
plhs[0] = data;
return;
}