DLL C++ do C

Odpowiedz Nowy wątek
2011-08-15 13:21
0

Witam,

nie za bardzo się na tym znam, ale muszę jakoś przełożyć konstruktor z C++ do funkcji, która będzie dostęna potem dla labVIEW. Zupełnie nie znam się na wrapperach.

Konstruktor :

 
Klasa::Klasa(const string& typ, size_t liczba)
: Kasa2(typ, liczba), n_t(liczba)
{
    assert(cout << "Klasa::Klasa() is called\n");
    MutexLocker lock(mutex);
    realloc(n_t);
}
edytowany 1x, ostatnio: dziech, 2011-08-15 13:21

Pozostało 580 znaków

2011-08-15 14:57
typedef void* PKlasa;
 
extern "C" void Klasa_Create(PKlasa *obj, const char* typ, size_t liczba)
{
   obj = (PKlasa)new Klasa(string(typ),liczba);
}

nie sprawdzane. chodzi o zasadę. możesz też zwracać zmienną typu PKlasa.
zależnie od tego co to jest Klasa, możesz spróbować udostępnić ten typ bezpośrednio dla C (z wyłączeniem metod), albo traktować jako "black box", tylko jako wskaźnik.

edytowany 1x, ostatnio: Azarien, 2011-08-15 15:00

Pozostało 580 znaków

2011-08-16 12:50
0

Hmm, no dobrze, a jeśli mam jeszcze bardziej złożony konstruktor ? Dziękuję za odp ; )

 
OD::OD(const string& type, size_t n)
: MD(type, n_channels), n_t() {...}
 

MD jest public : przy okazji, jak to można zwrappować. Ech, męczące jest to, czemu Labview nie rozumie Cpp !

 class AOK_API OD : public MD {...}

Pozostało 580 znaków

2011-08-16 13:35
0

a jeśli mam jeszcze bardziej złożony konstruktor ?

A jakie to ma znaczenie? Byleby konstruktor dostał poprawne parametry.

czemu Labview nie rozumie Cpp !

Dlatego, bo C++ nie ma sensownego ABI, tak jak to ma miejsce w przypadku C.

Przecież jest, jedyne słuszne Visual C++ - othello 2011-08-16 13:54
Pisałem o ABI (Application Binary Interface), a nie IDE ;P - _0x666_ 2011-08-16 13:58
Mi chodziło o kluczowanie (wg wikpedii "dekorowanie") nazw w przy eksporcie klas C++, Visual ma swoje, Boralnd ma swoje itd. Chyba to właśnie miałeś na myśli mówiąc o ABI ?:> - othello 2011-08-16 14:01
Tak (choć pewnie znalazłoby się coś jeszcze). - _0x666_ 2011-08-16 14:04
znalazłaby się jeszcze cała reprezentacja obiektu: położenie wskaźnika na vtable metod wirtualnych, szczególnie przy dziedziczeniu wielokrotnym albo wirtualnym. kolejność pól w pamięci i ich wyrównanie (nikt w zasadzie nie gwarantuje, że będzie to kolejność wg deklaracji). a reprezentacja "wskaźników do składowych" to już w ogóle bajka. chwila, co zostało? aaa - wyjątki. ktoś wspominał o wyjątkach? - Ranides 2011-08-20 17:51
Zapewne, chociaż name mangling i tak juz zamyka drogę do kompatybliności, więc reszta i tak nieważna, czy mylę się?? - othello 2011-08-21 14:25

Pozostało 580 znaków

2011-08-16 22:39
0

Ech, męczące jest to, czemu Labview nie rozumie Cpp !
Twoim problemem jest to, że DLL-ka (twoja?) udostępnia API w postaci klas C++ zamiast zestawu funkcji C. Dla uniknięcia tego typu problemów, każda DLL-ka powinna eksportować globalne funkcje, a nie klasy. W ten sposób można jej będzie użyć w każdym języku programowania, a nie tylko i wyłącznie w C++ i to tylko i wyłącznie danym kompilatorze.

Ech, męczące jest to, czemu Labview nie rozumie Cpp !
trochę. National Instruments to jedyna firma (z jaką się spotkałem) która na poważnie wypuszcza środowiska do czystego C.

Pozostało 580 znaków

2011-08-19 10:20
0

No dobrze, a jeśli nie potrzebuję dostępu do środka klasy bezpośrednio, to czy możliwe jest coś takiego :

#define DLLIMPORT __declspec (dllexport)
 
[moje include ""]
#include <sstream>
#include <stdexcept>
#include <memory>
 
using namespace std;
using namespace adocol;
 
ODev* device2;
CDev* cdev;
ODev* device1;
 
extern "C" {
 
DLLIMPORT void ReadDMC(const char* fileName)
{
\\początek [...] - oznacza, że wyciąłem kod ze względów estetycznych
 
   auto_ptr<Data> newdata;
   try {
      newdata = auto_ptr<Data>(new Data(string(fileName))); }
   catch [...]
   try{
      device1 = newdata->createOutput(); }
   [...]
}
 
DLLIMPORT   void setVoltages(const double* vlt) {
      device1->set(vlt);
   }
 
DLLIMPORT   void setZernike(const double* zer) {
      device2->set(zer);
      cdev->sweep();
   }
 
   BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason ) 
    { 
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;
 
        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;
 
        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;
 
        case DLL_PROCESS_DETACH:
         {
         delete device1;
       delete device2;
       delete cdev;
       device1 = NULL;
       device2 = NULL;
       cdev = NULL;
         }
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
   }
 
} 

Po wstawieniu if(deviceX) jako warunek wykonania instrukcji, DLL działa. Czyli błąd, który jest dalej wynika podczas tworzenia obiektów w funkcji ReadDMC... Co to może być ? : /

edytowany 1x, ostatnio: dziech, 2011-08-19 11:44

Pozostało 580 znaków

2011-08-19 11:46
0

jeśli wystarczą ci globalne obiekty klasy i wiesz z góry ile ich będzie, to można.

Pozostało 580 znaków

2011-08-19 11:52
0

Zedytowałem i może nie widziałeś ; ) DLL dalej leci błąd.

Po wstawieniu if(deviceX) jako warunek wykonania instrukcji, DLL działa. Czyli błąd, który jest dalej wynika podczas tworzenia obiektów w funkcji ReadDMC... Co to może być ? : /

Pozostało 580 znaków

2011-08-29 18:27
0

hej : )

Dalej się męczę z tym tematem, ale mam pytanie : mam char array[] i mam funkcję, która jako argument przyjmuje const char* array. W jaki sposób przeprowadzić konwersję ? Próbowałem strcpy. Cóż, pomijając, że do funkcji i tak przekazuję pointer, więc nie muszę konwertować, ale być może tutaj jest problem dla LabVIEW... Kto wie : D Debbuger nie ogarnia co LV robi ; )

Następna sprawa - mam DLL, która działa. Przypuśćmy, że jest w niej właśnie funkcja

 void setVoltages(double* vlt){obiekt1.funkcjaobiektux(vlt);}
void read(char* array){ // etc.}
void free() {delete obiekt1; obiekt1 = NULL;}

Napisałem drugie DLL, które zlinkowałem z tym "starym" DLL. I tam wrzuciłem funkcję (prototyp zgodny z tym, co chce LabVIEW - nie mogę zmienić)

 void LV_funUP(char array[], double vlt[])
{read(array);
setVoltages(vlt);
free();
}

Problem w tym, że nie działa. Nawet jako exe, pomijając LV...

edytowany 1x, ostatnio: dziech, 2011-08-29 18:28

Pozostało 580 znaków

2011-08-29 19:34
0

nie musisz kopiować danych, przekazywałem wskaźniki na char pomiędzy Visual C++ a LabWindows i działało w obie strony.

Pozostało 580 znaków

2011-08-29 19:35
0

No właśnie... powinno działać, ale nie działa. Funkcja read zwraca 0, czyli nie tworzy obiektów wewnątrz. Nie wiem co może być przyczyną....

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0