Используя MATLAB Compiler Runtime (mcr), я создал dll файла matlab. Я могу использовать функцию и передавать все переменные функции легко и без проблем.
Моя проблема в том, что у меня есть класс с "mwArray" как переменная в нем, например:
#include <samplemmfile.h>
#include <mclmcr.h>
#include <stdio.h>
class MModel{
int x;
mwArray y;
};
и затем я создаю из него объект, приложение во время выполнения генерирует исключение в файле заголовка "mclcppclass.h":
Access violation executing location 0X0000000000.
Было бы довольно дорого обернуть и преобразовать все входные файлы в формат matlab каждый раз, когда я хочу называть эти функции, поэтому было интересно, есть ли какие-либо решения для этой проблемы?
Благодаря,
Спасибо, моя проблема была решена на самом деле! проблема заключается в том, что инициализация должна быть выполнена до создания любого экземпляра класса, который содержит объект mwArray.
Например, следующий код сработает с самого начала:
Class1.h:
#include "libInnerProduct.h"
class Class1
{
public:
Class1()
: a(1, 2, mxDOUBLE_CLASS), b(1, 2, mxDOUBLE_CLASS) {
double aa[] = {1 , 2};
double bb[] = {5 , 7};
a.SetData(aa, 2);
b.SetData(bb, 2);
}
double innerproduct() {
mwArray c;
InnerProd(1, c, a, b);
return (double)c;
}
private:
mwArray a, b;
};
Class2.h:
#include "Class1.h"
#include <mclmcr.h>
#include <mclcppclass.h>
class Class2
{
public:
Class2(){
if (!mclInitializeApplication(NULL,0) || !libInnerProductInitialize()) {
std::cerr << "failed to initialize" << std::endl;
exit(1);
}
obj=new Class1();
}
~Class2(){
libInnerProductTerminate();
mclTerminateApplication();
}
double inp(){
return obj->innerproduct();
}
private:
Class1* obj;
};
int main()
{
Class2 obj;
double sum = obj.inp();
std::cout << sum << std::endl;
return 0;
}
но если вы поместите часть инициализации перед тем, как получить экземпляр класса Class 2, все будет хорошо. Кроме того, вы также не можете иметь экземпляр Class2 из основного!
Ура,
Я попытался с простым примером на моем конце (я повторно использую предыдущий пример), но я не могу воспроизвести проблему.
Функция MATLAB, которую мы упаковываем, такова:
function c = MyAdd(a,b)
c = a + b;
end
Скомпилирован в общую библиотеку C++ с использованием mcc
компилятора:
>> mcc -N -W cpplib:libMyAdd -T link:lib MyAdd.m -v
Далее здесь C++ программа для тестирования библиотеки. Я создал класс, содержащий два экземпляра mwArray
:
#include "libMyAdd.h" // generated library
class MyClass
{
public:
MyClass()
: a(2, 2, mxDOUBLE_CLASS, mxREAL), b(2, 2, mxDOUBLE_CLASS, mxREAL) {
double aa[] = {1.0, 2.0, 3.0, 4.0};
double bb[] = {5.0, 6.0, 7.0, 8.0};
a.SetData(aa, 4);
b.SetData(bb, 4);
}
mwArray add() {
mwArray c;
MyAdd(1, c, a, b);
return c;
}
private:
mwArray a, b;
};
int main()
{
if (!mclInitializeApplication(NULL,0) || !libMyAddInitialize()) {
std::cerr << "failed to initialize" << std::endl;
return -1;
}
try {
MyClass obj;
mwArray sum = obj.add();
std::cout << "a + b = \n" << sum << std::endl;
} catch (const mwException& e) {
std::cerr << e.what() << std::endl;
return -2;
} catch (...) {
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
libMyAddTerminate();
mclTerminateApplication();
return 0;
}
Вышеупомянутое работает просто отлично:
>> mbuild testMyAdd.cpp libMyAdd.lib -v
C:\> testMyAdd.exe
a + b =
6 10
8 12
MyClass
будет работать до инициализации MCR (что плохо!). Как я уже говорил в комментариях, вы нужно быть осторожным с порядком инициализации вещей ... Вы должны будете изменить класс MyClass
чтобы управлять его собственными зависимостями, используя некоторый вид статических членов, чтобы гарантировать, что mclInitializeApplication
вызывается, до того, как будет создан экземпляр класса
mclInitializeApplication
) и библиотеку (libXXXInitialize
) перед использованием любого из них? Вы должны быть осторожны с порядком того, как все устроено, когда у вас есть классы.