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

2 ビュー (過去 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];
}

カテゴリ

Help Center および File ExchangeC Shared Library Integration についてさらに検索

製品

Community Treasure Hunt

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

Start Hunting!

Translated by