loadlibrary и C++ заглавни файлове

Написах някои функции и създадох dll чрез C++ кодове и използвах някои от C++ заглавните файлове. Но открих, че loadlibrary поддържа само C заглавни файлове и получавам тази грешка:

Error using loadlibrary (line 419)
Failed to preprocess the input file.
Output from preprocessor is:LargeBaseConvertorClass.h
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\eh.h(26) : fatal error    C1189: #error :  "eh.h is only for
C++!"

Не искам да променям кодовете си и не искам да използвам mex функции.

Как мога да използвам своя C++ dll в matlab? (имам нужда от много)

Благодаря.

Да Али.


person Mohammad Reza Ramezani    schedule 23.10.2014    source източник
comment
Покажете командата matlab, която сте използвали, моля.   -  person KitsuneYMG    schedule 23.10.2014
comment
loadlibrary('e:/LargeBaseConvertorDll.lib', 'e:/LargeBaseConvertorClass.h')   -  person Mohammad Reza Ramezani    schedule 23.10.2014
comment
На коя операционна система? С кои команди? Моля, редактирайте въпроса си, за да го подобрите!   -  person Basile Starynkevitch    schedule 23.10.2014


Отговори (2)


Правил съм две неща, за да се справя с това преди.

Първият е да напишете C обвивка около C++ кода.

//foo_c_wrapper.h
#ifndef FOO_C_WRAPPER_H
#define FOO_C_WRAPPER_H

#ifdef __cplusplus
extern "C" {
#endif
typedef void* FOO_HANDLE;//can use a predeclared pointer type instead
FOO_HANDLE init_foo(int a);
void bar(FOO_HANDLE handle);
void destroy_foo(FOO_HANDLE** handle);
//ect
#endif

//foo.hpp
#ifndef FOO_HPP
#define FOO_HPP
class Foo {public: Foo(int); ~Foo(); void bar();}
#ifdef __cplusplus
}
#endif
#endif

//foo_c_wrapper.cpp
#include "foo_c_wrapper.h"
#include "foo.hpp"
extern "C" {
FOO_HANDLE init_foo(int a) {return new Foo(a);}
void bar(FOO_HANLDE handle) {
   Foo* foo = reinterpret_cast<Foo*>(handle);
   foo->bar();
}
void destroy_foo(FOO_HANDLE** handle) {
   Foo** foo = reinterpret_cast<Foo**>(handle);
   delete *foo;
   *foo = NULL;
}
}

Другата опция е да създадете потребителски mex файл. За съжаление тази тема е твърде обширна, за да навлизам в подробности тук, така че ще считам „Създаване на C++ съвместим Mex файл“ като обобщение на следната връзка:

http://www.mathworks.com/help/matlab/matlab_external/c-mex-file-examples.html#btgcjh1-14

person IdeaHat    schedule 23.10.2014
comment
+1 определено е по-лесно просто да създадете MEX-функция за взаимодействие с библиотеката, особено ако е C++, а не C (MEX API не е толкова труден за използване). Забравете за loadlibrary - person Amro; 25.10.2014
comment
Моите два цента са, че ако се опитвате да направите библиотеката си изключително съвместима, тогава C пътят може да си струва в дългосрочен план... ще трябва да поддържате обвивка и в двата случая, може и да поддържате обвивката което ви позволява да взаимодействате с куп неща. - person IdeaHat; 26.10.2014

Направих това в миналото, като създадох няколко C интерфейсни функции за създаване и манипулиране на C++ обекти. Това прави възможно лесното използване на C++ код от Matlab, без да се налага да го модифицирате. Докато заглавката е само C, Matlab не се оплаква, ако накрая са създадени C++ обекти.

Например, ако класът, който искате да използвате от Matlab, е:

class MyClass
{
public:
    double memberFunction();
};

Имате заглавен файл (добавете префикс, за да експортирате функции):

int createObject();
double callFunction( int object );

Нека cpp файлът е нещо като:

static std::map<int,MyClass*> mymap;

int createObject()
{
    MyClass* obj = new MyClass();
    int pos = mymap.size();
    mymap[pos] = obj;
    return pos;
}

double callFunction( int obj )
{
    return mymap[obj]->memberFunction();
}

Сега можете да създавате MyClass обекти и да осъществявате достъп до членове от Matlab.

Ще трябва да подадете повече параметри, да се справите по-добре със съдържанието на картата (проверете дали обектът съществува в картата и върнете грешки, ако не, изтрийте обекти от картата, когато сте готови... и т.н.), но това е общата идея.

person jpo38    schedule 23.10.2014