MATLAB Answers

Using calllib with a function that uses std::vector in its prototype

6 ビュー (過去 30 日間)
Dan K
Dan K 2016 年 5 月 17 日
コメント済み: mezaguer karima 2019 年 7 月 23 日
Hi folks,
Is there any way to use loadlibrary/calllib to call a function in a DLL where the function is expecting a std::vector as one of the inputs? Or am I trying to do something impossible?
Here is what I get when I try to run loadlib using a header file that includes address pointers (&) to two std::vector.
Warning: Warnings messages were produced while parsing. Check the functions you
intend to use for correctness. Warning text can be viewed using:
[notfound,warnings]=loadlibrary(...)
> In loadlibrary
Error loading library intermediate output follows.
The actual error is at the end of this output.
*********
Failed to parse type 'std :: vector < double >* filterCoeffs' original input 'std :: vector < double >& filterCoeffs '
Found on line 23 of input from line 68 of file C:\\_EMILY\\NASARovers_2328\\NASARovers\\Matlab\\Matlab_Rovers_header2.h
Error parsing argument for function filtfilt_1D function may be invalid.
Failed to parse type 'std :: vector < double >* toFilter' original input ' std :: vector < double >& toFilter '
Found on line 23 of input from line 68 of file C:\\_EMILY\\NASARovers_2328\\NASARovers\\Matlab\\Matlab_Rovers_header2.h
Error parsing argument for function filtfilt_1D function may be invalid.
*********
Error using loadlibrary
Building NASARovers_thunk_pcwin64 failed. Compiler output is:
C:\TDM-GCC-64\bin\gcc -I"C:\Program Files\MATLAB\R2016a\extern\include"
-fexceptions -fno-omit-frame-pointer -I"C:\MATLAB"
-I"C:\_EMILY\NASARovers_2328\NASARovers\Matlab" "NASARovers_thunk_pcwin64.c" -o
"NASARovers_thunk_pcwin64.dll" -shared
In file included from NASARovers_thunk_pcwin64.c:27:0:
C:\_EMILY\NASARovers_2328\NASARovers\Matlab/Matlab_Rovers_header2.h:68:37:
error: expected ')' before ':' token
NASAROVERS_CAPI void filtfilt_1D(std::vector<double>& filterCoeffs,
std::vector<double>& toFilter);
^
NASARovers_thunk_pcwin64.c:141:29: error: expected '=', ',', ';', 'asm' or
'__attribute__' before ':' token
EXPORT_EXTERN_C void
voidstd::vector<double>&filterCoeffsstd::vector<double>&toFilterThunk(void
fcn(),const char *callstack,int stacksize)
  1 件のコメント
mezaguer karima
mezaguer karima 2019 年 7 月 23 日
hello i have seen your question i'm in the same probleme i have this in my program std::vector<unsigned int> vuiInterfaces(MAX_INTERFACE_COUNT) C++ and i don't know how to use it in matlab (MAX_INTERFACE_COUNT= 5 here) this is the part of c++ code, how can i convert this vector into matlab to use it
thanks
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include "InterfaceLLT_2.h"
#include "PartialProfile.h"
using namespace std;
static CInterfaceLLT* m_pLLT = NULL;
static unsigned int m_uiResolution = 0;
static TScannerType m_tscanCONTROLType = scanCONTROL2xxx;
int main(int argc, char* argv[])
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
std::vector<unsigned int> vuiInterfaces(MAX_INTERFACE_COUNT);
std::vector<DWORD> vdwResolutions(MAX_RESOULUTIONS);
unsigned int uiInterfaceCount = 0;
unsigned int uiShutterTime = 100;
unsigned int uiIdleTime = 900;
TScannerType ScannerType = scanCONTROL2xxx;
bool bLoadError = false;
int iRetValue = 0;
bool bOK = true;
bool bConnected = false;
// Creating a LLT-object
// The LLT-Object will load the LLT.dll automaticly and give us a error if ther no LLT.dll
m_pLLT = new CInterfaceLLT("..\\LLT.dll", &bLoadError);
if (bLoadError)
{
cout << "Error loading LLT.dll \n";
// Wait for a keyboard hit
while (!_kbhit()) {}
// Deletes the LLT-object
delete m_pLLT;
return -1;
}
// Create a Device
if (m_pLLT->CreateLLTDevice(INTF_TYPE_ETHERNET))
cout << "CreateLLTDevice OK \n";
else
cout << "Error during CreateLLTDevice\n";
// Gets the available interfaces from the scanCONTROL-device
iRetValue = m_pLLT->GetDeviceInterfacesFast(&vuiInterfaces[0], (unsigned int)vuiInterfaces.size());
if (iRetValue == ERROR_GETDEVINTERFACES_REQUEST_COUNT)
{
cout << "There are more or equal than " << vuiInterfaces.size() << " scanCONTROL connected \n";
uiInterfaceCount = (unsigned int)vuiInterfaces.size();
}
else if (iRetValue < 0)
{
cout << "A error occured during searching for connected scanCONTROL \n";
uiInterfaceCount = 0;
}
else
{
uiInterfaceCount = iRetValue;
}

サインインしてコメントする。

採用された回答

Philip Borghesani
Philip Borghesani 2016 年 5 月 17 日
What you are trying won't work.
loadlibrary only supports calling functions that are callable from C and header files that can be parsed by a c compiler. Any functions written in C++ must be extern "C" and std:vector or any class or template type can't be used for input or output arguments.
I will suggest the documentation make this a bit more explicit.
  1 件のコメント
Dan K
Dan K 2016 年 5 月 17 日
I was afraid that was going to be the answer, but was hoping I was wrong. Many thanks.

サインインしてコメントする。

その他の回答 (2 件)

Todd Leonhardt
Todd Leonhardt 2016 年 5 月 18 日
編集済み: Todd Leonhardt 2016 年 5 月 18 日
As mentioned, you can't really use calllib with most C++ code.
However, you can use mex to build a MATLAB Executable (MEX) function from C++ source code: http://www.mathworks.com/help/matlab/ref/mex.html
MEX is relatively flexible in that it will let you also link to C++ static and dynamic libraries as well as compile source code. It is a little bit more work in that you need to create a wrapper mexFunction and deal with marshaling data between MATLAB and C/C++, but it is MUCH more flexible than calllib.

Dan K
Dan K 2016 年 5 月 20 日
編集済み: Dan K 2016 年 5 月 20 日
In case anybody has stumbled across this question, I will tell you what my final solution ended up being. For each top level function that uses std::vectors as inputs or outputs, I wrote a wrapper function that surrounds it, taking standard data pointers and the size of the intended vector and constructs the vectors before calling the actual function I wanted to test. Then repeat the process once the function has returned.
Example:
void InterpolateDelayEst_MLTest(
double* delayEstRawPtr, double* delayEstPtr, UINT32 nRaw, FLOAT32 delayEstBW, UINT32 interp_scalar_m_length)
{
// Create the vectors that the data is going to be dropped into:
std::vector<FLOAT32> delayEstRaw(nRaw);
std::vector<FLOAT32> delayEst(interp_scalar_m_length);
for (UINT32 i = 0; i < nRaw; i++)
delayEstRaw[i] = (FLOAT32)delayEstRawPtr[i];
// Call the actual function that we are interested in testing:
InterpolateDelayEst(delayEstRaw, delayEst, delayEstBW, interp_scalar_m_length);
// Copy the data from the returned vector into the array whose pointer was passed in.
for (UINT32 i = 0; i < interp_scalar_m_length; i++)
delayEstPtr[i] = (double)delayEst[i];
}

Community Treasure Hunt

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

Start Hunting!

Translated by