Introduction
我想用Qt查询COM函数。我有一个文件,但VB除外。然而,这位医生说:
Object.Frequencies DataArray
Object -> An object expression that evaluates to a BKDataSet object.
DataArray -> An array of strings or an array of values The DataArray structure must be declared in the application that is controlling PULSE and the size of the array must be equal to the number of x-axis entries. In Visual Basic, use the DIM (or corresponding) statement to declare the variable and allocate storage space. In other languages use a safearray of strings (VT_BSTR) or reals (VT_R8 for double or VT_R4 for float/single).
步骤1
首先,我使用奥列维来查看函数原型的真实外观。
我找到了:void Frequencies(VARIANT* FrequencyArray)。
所以我试着用Qt:
IBKDataSet *data = function->FunctionData();
int nbFrequencies = data->dynamicCall("GetNumberOfXAxisEntries()").toInt();
QList<QVariant> frequencies;
for(int i=0; i<nbFrequencies; j++) {
frequencies << 0.0;
}
QList<QVariant> parameters;
parameters << QVariant(frequencies);
data->dynamicCall("Frequencies(QVariant&)", parameters);
for(int i=0; i<frequencies.size(); i++) {
qDebug() << frequencies.at(i);
}注意:我使用了QList<QVariant>,如这里所示。
但我收到了以下消息:Type Mismatch in Parameter. Pass an array of type string or real.。
步骤2
因此,我尝试使用一个字符串数组:
IBKDataSet *data = function->FunctionData();
int nbFrequencies = data->dynamicCall("GetNumberOfXAxisEntries()").toInt();
QList<QString> frequencies;
for(int i=0; i<nbFrequencies; i++) {
frequencies << "0.0";
}
QList<QVariant> parameters;
parameters << QVariant(frequencies);
data->dynamicCall("Frequencies(QList<QString>&)", parameters);
for(int j=0; j<frequencies.size(); j++) {
qDebug() << frequencies.at(j);
}没有错误,但返回的值是在初始化期间设置的值(我尝试了几个值,而不仅仅是0.0)。
步骤3
在那之后,我尝试了许多组合,但都没有成功。因此,我要求开发人员(难以联系)提供一个例子。他们给我发送了以下代码(Visual++):
IBKDataSetPtr bkDataSet(function->FunctionData);
int nEntries = bkDataSet->GetNumberOfXAxisEntries();
COleSafeArray safeArray;
safeArray.CreateOneDim( VT_R8, nEntries);
COleVariant vDontCare;
bkDataSet->Frequencies(&safeArray);
double* pFrequencyData;
safeArray.AccessData((void**)&pFrequencyData);
CString sMessage;
sMessage.Format("Y[1] = %1.4e ", pFrequencyData[1]);
MessageBox(sMessage);
safeArray.UnaccessData();问题
如何在QtCreator?中使用此代码
我意识到COleSafeArray是VisualStudio特有的..。
我为这篇文章的篇幅感到抱歉,但这是一段时间,我试图绕过这个问题,但没有成功。
编辑
下面是关于如何使用WIN32 API实现此操作的一个线索:
QList<double> getCOMValues(IDispatch *dispatch, const QString &method, int arraySize) const {
QList<double> result;
HRESULT hr;
// I don't know how to convert a QString into an OLECHAR*
OLECHAR * szMember = L"Frequencies";
DISPID dispid;
// Retrieve the dispatch identifier for the method.
// Use defaults where possible.
hr = dispatch->GetIDsOfNames(IID_NULL, &szMember, 1, LOCALE_USER_DEFAULT, &dispid);
// Test return is OK
if(FAILED(hr)) {
qDebug() << "Error while trying to read the " << method;
return result;
}
// Defines a SAFEARRAY.
SAFEARRAY *psa;
// Represents the bounds of one dimension of the array.
SAFEARRAYBOUND freqBound[1];
// The lower bound of the dimension starts at 0.
freqBound[0].lLbound = 0;
// The number of elements in the dimension is the number of frequencies.
freqBound[0].cElements = arraySize;
// Creates a new array descriptor, allocates and initializes the data for
// the array, and returns a pointer to the new array descriptor.
// VT_R8 represents double.
// 1 is the number of dimensions in the array.
psa = SafeArrayCreate(VT_R8, 1, freqBound);
// Check the array is not NULL.
if(psa == NULL) {
qDebug() << "Error while trying to read the " << method;
return result;
}
// This is the default value to put into the array.
double init[] = {0.0};
// Populates the array with 0.0.
for(long index=0;index<arraySize;index++)
{
// Stores the data element at the specified location in the array.
hr = SafeArrayPutElement(psa,&index,init);
if( FAILED(hr)) {
qDebug() << "Error while initialising the array for " << method;
}
}
// Describes arguments passed within DISPPARAMS.
VARIANTARG v[1];
// A safe array descriptor, which describes the dimensions, size, and in-memory location of the array.
v[0].parray = psa;
// The type of data in the union.
v[0].vt = VT_ARRAY|VT_R8;
// Contains the arguments passed to a method or property.
DISPPARAMS params = {v, NULL, 1, 0};
// To catch errors
EXCEPINFO pExcepInfo;
// Provides access to properties and methods exposed by the object.
hr = dispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, ¶ms, NULL, &pExcepInfo, NULL);
if(FAILED(hr)) {
if(hr == DISP_E_EXCEPTION) {
printf("%S\n", pExcepInfo.bstrSource);
printf("%S\n", pExcepInfo.bstrDescription);
}
qDebug() << "Error while trying to read the " << method;
return result;
}
double res = 0;
for(long idx=0; idx<arraySize; idx++) {
hr = SafeArrayGetElement(psa, &idx, &res);
if(hr == S_OK) {
result.push_back(res);
} else {
result.push_back(0.0);
qDebug() << "Error while trying to read the " << method;
}
}
// Clears the variant.
hr = VariantClear(v);
return result;
}但是Invoke方法返回一个DISP_E_EXCEPTION: Type Mismatch in Parameter. Pass an array of type string or real.
发布于 2013-06-24 07:03:04
发现问题了。很简单!
IBKDataSet *data = function->FunctionData();
int nbFrequencies = data->dynamicCall("GetNumberOfXAxisEntries()").toInt();
QList<QString> frequencies;
for(int i=0; i<nbFrequencies; i++) {
frequencies << "0.0";
}
QList<QVariant> parameters;
parameters << QVariant(frequencies);
data->dynamicCall("Frequencies(QList<QString>&)", parameters);
frequencies = parameters.first().toStringList();
for(int j=0; j<frequencies.size(); j++) {
qDebug() << frequencies.at(j);
}我必须阅读parameters的第一个元素并将其转换为一个QStringList.
https://stackoverflow.com/questions/17195318
复制相似问题