Azzera filtri
Azzera filtri

actxserver​('ADODB.Co​nnection') doesn´t work on Matlab Production Server

5 visualizzazioni (ultimi 30 giorni)
I have the following code running on Matlab Production Server :
function tblResultados = AnalisisCorrelacion(flag)
% numInput is assumed/expected to be numeric
if iscell(flag) % Convert to a vector/matrix if needed
flag = cell2mat(flag);
end
if isrow(flag) % Transpose the input if needed
flag = flag';
end
if flag == 1
cn = actxserver('ADODB.Connection');
set(cn,'CursorLocation',3);
%Open connection
invoke(cn,'Open', 'provider="myprovider";mode=Read;USER ID="myuser";Password="mypassword";Data Source="serverIPaddr";');
sql = ['SET starttime= now-1h,endtime=now,samplingmode=calculated, CalculationMode= Average,intervalmilliseconds=1m ,select ,value,' ...
'from "mytable WHERE" tagname LIKE "mytag"'];
%Run query and return results
tblResultados=adodbquery(cn,sql);
end
end
This code works well on local PC but on Matlab Production Server issue the following error :
Server Creation Failed: CoInitialize has not been called
Error in AnalisisCorrelacion (line 13)
While processing request 70682411008)
Error in actxserver (line 89)
{Error using feval

Risposte (1)

Divyanshu
Divyanshu il 15 Nov 2023
Hi Leonardo,
I understand that your code executes properly on local PC but when executed on MATLAB Production Server (MPS) you are facing the issue. Refer the following points to get better understanding of the problem:
  • When a MPS worker is called first time, this starts a thread and 'CoInitialize' is called on this thread.
  • Call to 'CoInitialize' initializes COM interface on this thread.
  • If you make a call to different CTF on this same worker, then a new thread is started.
  • However, CoInitialize is not called for this new thread and hence COM interface is not initialized. Now using 'actxserver' on this thread would fail.
A workaround for this issue is to call 'CoInitializeEx' from this thread. Implement the following .cpp file:
#include "mex.h"
#include <Objbase.h>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
HRESULT r;
/* Print the ID of the current thread */
DWORD th = GetCurrentThreadId();
mexPrintf("Calling CoInitializeEx(NULL,COINIT_APARTMENTTHREADED) on thread %0.8x\n",th);
/* Simply call CoInitializeEx */
r = CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);
/* This can return S_OK if CoInitialize had not been called before and
* it was now called successfully. In that case, just continue, do not
* call CoUninitialize; we actually need the thing to be initialized
* for the COM work we are doing in MATLAB.
* It may also return S_FALSE which is an indication CoInitialize had
* been called successfully before and the new call didn't really do
* anything. As documented on https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializeex
* we should still CoUninitialize this call then; do it once, to
* counteract what we just did but leave the original instance intact.
*/
if (r == S_FALSE) {
mexPrintf("CoInitializeEx returned S_FALSE, calling CoUninitialize.\n");
CoUninitialize();
}
/* Return the return code to MATLAB */
plhs[0] = mxCreateDoubleScalar(r);
}
Compile the above .cpp file using C++ compiler and then simply always call this before the first call to "actxserver" in your code.

Categorie

Scopri di più su MATLAB Compiler in Help Center e File Exchange

Prodotti


Release

R2023a

Community Treasure Hunt

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

Start Hunting!

Translated by