[c++/cli] Eksport klas do DLL

0

Witam wszystkich.

W jaki sposob wyeksportowac do DLL wlasna klase?

Mam klase Node, w niej pola cX, cY, etc....

zgodnie z tym co jest napisane tutaj: http://msdn.microsoft.com/en-us/library/twa2aw10.aspx oraz wedle przykladu stad: http://msdn.microsoft.com/en-us/library/ms235636.aspx moge wyeksportowac zarowno metody/funkcje jak rowniez same pola-wartosci..

Problem w tym, ze w trakcie eksportu (na etpaie build..) otrzymuje komunika o bledzie:

1>...\node.h(10) : error C2071: 'Node::cX' : illegal storage class

Jak uporac sie z tym problemem? Jak wyoksportowac wlasna klase oraz funkcje , dla ktorych obiekt tej kalsy bedzi eargumentem? Docelowo chce, aby inna osoba jedynie zaimportowala DLL'ke i wywolywala funkcje, dla ktorej element mojej klasy bedzi eparametrem..

pozdrawiam
R

..zaglebiajac sie w tresci z MSDNa dochodze do wniosku, ze do DLL moge eksportowac jedynie funkcje...
??

0

tzn wyeksportować klasę z DLLki możesz przy połączeniu statycznym...
class __declspec(dllexport) name
{
[...]
};
wystarczy, że będziesz miał w pliku nagłówkowym definicję klasy, i zlinkujesz statycznie DLLkę, która będzie miała jej metody...

Jeśli chodzi ci o dynamiczny eksport metod klasy z DLLki, to także na pewno musisz mieć plik nagłówkowy z definicją klasy, ale dynamiczne linkowanie metod tak jak funkcji przez GetProcAddress jest także możliwe, nie wiem jak to się wykonuje, ale zaleciłbym ci poszukanie odpowiedzi w plikach nagłówkowych GDI+, bo tam jest to zrealizowane, GDI+ jest biblioteką podłączaną dynamicznie, a przecież jest w niej wiele metod klas GDI+, wiem, że podłączenie odbywa się za pomocą funkcji, jedna funkcja inicjuje bibliotekę, a druga zwalnia...

0

O ile dobrze pamiętam, wyglądało to w ten sposób, że w dll'e robiłeś f-cje, która zwracała nowy obiekt.

0

crayze z tego co pamiętam, GDI+ na poziomie eksportów to zwykłe funkcje, uchwyty itd. Te klasy, o których piszesz, zdefiniowane są w plikach nagłówkowych.

0

Dokladnie, GDI+ esportuje tylko funkcje, do ktorych mozna zreszta odwolywac sie i bezposrednio (GDI+ Flat Api - http://msdn.microsoft.com/en-us/library/ms533969(VS.85).aspx )
W nagłówkach są natomiast wrappery C++

Jeszcze inne wyjście to eksportować funkcję, która będzie konstruować odpowiednie obiekty i zwracać wskaźnik - ma to jeszcze tę zaletę ze takie dll-ki można użyc z dowolnym kompilatorem (jeżeli wyeksportujemy funkcję bez name mangling rzecz jasna)

0

Jeszcze inne wyjście to eksportować funkcję, która będzie konstruować odpowiednie obiekty i zwracać wskaźnik

Trzeba dodać, że metody takiej klasy muszą być wirtualne - zwracany wskaźnik to wskaźnik na interface. Niszczenie takiego obiektu powinno odbywać się za pomocą metody obiektu, a nie delete (vide IUnknown::Release).

0

Hej..

.. klasa siedzi w dll´ce... uzytkownik ma do neij dostep z malym ale... -> nie ma tam funckji/metody, ktora za jeden z argumentow przyjume obiekt klasy...

obrazowo

class Kwadrat {
...
...

bool porownajZkwadratem(Kwadrat drugi);
};

jak wyeksportowac takei cos? (uzytkonik widzi funkcje, jak tylko argumentem nie bedzie obiekt Kwadrat a np double..)

i kolejne pytanie, dlaczego jak mialem funckje

void funkcja (Kwadrat &cos);

to kompilator wyrzucil blad error C2059: syntax error : '&'

...czyzby oba problemy byly ze soba powiazane?

dodam, ze polecono mi (jako cos co dziala) nie budowanie dllki jak pokazano w MSDNie (czyli consolowa - dll - pusty projekt) ale poprzez nowy-projekt-class library..

0

Ale z czym masz problem tak w ogole? Juz wszystko zostalo napisane.... Wiesz jak importowac i eksportowac funkcje? To zrob tak samo z klasami :|

nie ma tam funckji/metody, ktora za jeden z argumentow przyjume obiekt klasy...

Czyli "nie ma" gdzie? Sprawdziles ze nie jest to eksportowane z dll? W klasie "jest" tylko to, co zadelkarujesz w naglowku, a cialo klasy jest w dll - to wszystko

0
othello napisał(a)

Czyli "nie ma" gdzie? Sprawdziles ze nie jest to eksportowane z dll? W klasie "jest" tylko to, co zadelkarujesz w naglowku, a cialo klasy jest w dll - to wszystko

Ino powiem tak, w klasie sa wszystkei funkcje (w naglowku, potem tez dodane ich definicje..)..

problem w tym, ze nie mam dostepu (po "podlaczeniu" DLL´ki do innego projektu) do tylko jednej funkcji.. funkcji ktora jako parametr przyjmuje wlasnie obiekt tej samej klasy, dla ktorej to zadeklarowana jest ta funckja..

[ech, z gory przepraszam, za brak porpawnej terminologii..

ozdrawiam

0

co dokladnie rozumiesz przez 'nie mam dostepu' ?

0
quetzalcoatl napisał(a)

co dokladnie rozumiesz przez 'nie mam dostepu' ?

uzytkownik korzystajacy z tej tworzonej DLLki pisze w VB...

wiec (juz o dolaczeniu DLLki do jego projektu):

Dim b As ITAdll.Node
        b.

i tu w ramach podpowiedzi wyswietlaja mi sie mozliwe funkcje, etc. ktore moghe wybrac... sa wszystkie poza tymi funkcjami, ktore jako argument przyjmuja obiekt klasy zdefiniowanej..

myslalem,ze moze nie moge wywolywac (gdy eksportuje DLL) takich funkcji.. wiec stworzylem klase, w ktorej mam zdefinowana jedna funkcje (jako parametr bierze obiekty innych klas).. efekt -> jak wczesniej, dla int, double, etc dziala, ale jak wstawie tam swoja kalse, ktora wczensiej zdefinowalem w dll - juz nie...

0

oo.. i teraz w koncu pojawilo sie najwazniejsze: VB. czyli to co Ty tak naprawde robisz, to tworzysz klase eksponujaca interface COM.. moze wiec problem tkwi w tym, ze nie jest ona z nim calkiem zgodna i dlatego VB nie potrafi sobie z nia poradzic? przykrój te klase maksymalnie, do niezbednego minimum ktore po skompilowaniu i wpieciu w VB pokaze ten problem i zamiesc tutaj kod. musisz cos miec nie tak z deklaracja klasy albo samego interface'u COM

0
quetzalcoatl napisał(a)

przykrój te klase maksymalnie, do niezbednego minimum ktore po skompilowaniu i wpieciu w VB pokaze ten problem i zamiesc tutaj kod.

hmm.. tzn co mam zrobic? :| (dziekuje za wyrozumialosc).

0
quetzalcoatl napisał(a)

przykrój te klase maksymalnie, do niezbednego minimum

dobra, sporbuje wywalic wszystko oprocz owej funkcji... z ktora mam problem :)

0

// ITAdll.h

#pragma once
#include <string>
#include <iostream>

using namespace System;

namespace ITAdll {
	public ref class Node
	{
		public:
			bool nodeVSnode (Node sec);	
	};
	
}

//ITAdll.cpp

// This is the main DLL file.
#include <iostream>
#include <iomanip>
#include "stdafx.h"

#include "ITAdll.h"

bool ITAdll::Node::nodeVSnode(Node sec)
{
	return true;
}

void ITAdll::Obsluga::noOb(Node raz, Node dwa)
{
	int i = 0;
}

To mam wrzucone do projektu... (New-Project-Class Library)..
kompiluje sie bez bledow i w efekcie mam swoja DLL´ke (tak utworzona, VB doposzcza... w innym przypadkuy (jak tworze tak jak jest w MSDN... to wywala ze mam sprawdzic czy jest prawidlowa. (COM, etc..)


Wchodze do projektu w VB... [acha, w obu przypadakch, c++ i VB - ten sam kompilator/srodowisko -> VS 2005]..

Dim node As ITAdll.Node

   
        node.

i nie widze owej funkcji nodeVSnode...

0

..rozszerzajac pytanie..

jak wyeksportowac cos takiego:

std::vector<String> wektorek;

(w klasie, dostep public)

w trakcie kompilowania wyskakuja bledy:

1>c:\...: error C4368: cannot define 'wektorek' as a member of managed ...: mixed types are not supported

O "mixed types" poczytalem tutaj ( http://blogs.msdn.com/branbray/archive/2005/07/20/441099.aspx) o STL.. do DLL tutaj(http://support.microsoft.com/kb/168958/en-us)... niemniej dalej nie wiem jak z tego wyjsc?

Ktos pomoze?

[oczywiscie poprzendi problem wciaz aktualny..]
pozdrawiam

0

kurcze blade.. i znowu objawienie.. piszesz nie w C++ tylko C++/CLI.. masz jeszcze jakeis niespodzianki?:) zmartwie Cie: vector<> nie wyeksportujesz.. mozesz natomiast spokojnie eksponowac .net'owe kolekcje - listy etc, wiec najprosciej Ci bedzie przerobic ten wektor na nie

nie mialem czasu niestety przepuscic w/w pryzklad u sibeie przez kompilator, ale skoro piszesz w c+/cli to nie powienienes miec absulutnie zadnych problemow z interopem z VB pod warunkiem, ze klasy ktore maja zostac wyeksportowane beda mialy interface w 100% .Netowy (czyli zero metod/pol/argumentow natywnych -- a tak walsnie jest w Twoim przykladzie).. pamietam ze przy eksponowaniu interfejsu COM pomaga atrybut [ComVisible(true)] -- probowales nadac go klasie? moze wlasnie o to chodzic

0
quetzalcoatl napisał(a)

kurcze blade.. i znowu objawienie.. piszesz nie w C++ tylko C++/CLI.. masz jeszcze jakeis niespodzianki?:) zmartwie Cie: vector<> nie wyeksportujesz.. mozesz natomiast spokojnie eksponowac .net'owe kolekcje - listy etc, wiec najprosciej Ci bedzie przerobic ten wektor na nie

nie mialem czasu niestety przepuscic w/w pryzklad u sibeie przez kompilator, ale skoro piszesz w c+/cli to nie powienienes miec absulutnie zadnych problemow z interopem z VB pod warunkiem, ze klasy ktore maja zostac wyeksportowane beda mialy interface w 100% .Netowy (czyli zero metod/pol/argumentow natywnych -- a tak walsnie jest w Twoim przykladzie).. pamietam ze przy eksponowaniu interfejsu COM pomaga atrybut [ComVisible(true)] -- probowales nadac go klasie? moze wlasnie o to chodzic

hmm... ale ja jestem "zielony"...
-> jak nadawac klasie atrybut ComVisible?
-> jakie to sa metody/pola/.. natywne? (juz teraz wole spytac o kazdy element, bo znow sie okaze ze czegos (wielu rzeczy) nie rozumiem i bede szukal bezskutecznie nie tam gdzie trzeba)
-> jak mi vector odpada... to praktycznie mam do przerobienia caly program... (tam wszystko w vectorach siedzi.. oki i w jednym zbiorze (set)... :| )
-> ja nie pojalem w pelni c++ a tu .NETowe podejscie..? (szok..)
-> co to CLI (w tym przypadku).

rownoczesnie szukam tez sam odpowiedzi na te pytania... (spokojnie nie siedze biernie)..

A twoje uwagi okazuje sie niezastapione jak do tej pory -> DZIEKUJE :)

pozdrawiam

0

-> jak nadawac klasie atrybut ComVisible?

using namespace System.ComponentModel;   //o ile dobrze pamietam:)

[ComVisible(true)]     //TU
public ref class X {...}

-> ja nie pojalem w pelni c++ a tu .NETowe podejscie..? (szok..)
-> jakie to sa metody/pola/.. natywne?

natywne (native) - w skrocie oznacza 'cos ze zwyklego c++', cos nie-.Net-owego
zarządzane (managed) - w skrocie oznacza 'cos .Net'owego', m.in. cos podlegajacego GarbageCollectorowi. tutaj, mam na mysli ze VB (szczerze - nie wiem jak VB.NET - a z niego korzystacie - ale chyba on tez..) jest w stanie operowac jedynie na obiektach COM i na pewnych podstawowych typach danych z ktorych sa one zbudowane

...
using namespace System;    //namespace z .Net

...
	public ref class Node     //REF oznacza klase .Net'owa, nie natywna
...

-> jak mi vector odpada... to praktycznie mam do przerobienia caly program... (tam wszystko w vectorach siedzi.. oki i w jednym zbiorze (set)... :| )

praktycznie wszystkie typy .Net'owe maja przelozenie na COM, wiec w przypadku komunikacji miedzy VB a c++/cli sprowadzaloby sie to do eksponowania w klasie jedynie rzeczy .Net'owych (czyli Int32, IntPtr, String (nie std::string!!), klasy ref itp..). Natywne c++'owe teez sie poniekad da.. ale jest bardzo bardzo duzo zabawy z tym.. albo przerob je na kolekcje z .net, albo samo eksponowane property przez ta klase zrob jako takowa kolekcje i synchronizuj (kopiuj dane z jednego w drugi i vice versa, tak aby byly zawsze spojne) ja z oryginalnym wektorem

-> co to CLI (w tym przypadku).
CLI:= Common Language Infrastructure, patrz http://en.wikipedia.org/wiki/Common_Language_Infrastructure
mowiac łopatologicznie jest to idea/architektura na ktorej zbudowano CLR, czyli engine .Net'a. a tak w ogole to nie mowilem o CLI tylko o C++/CLI :)
C++/CLI jest INNYM JEZYKIEM PROGRAMOWANIA niz C++. jest to rozszerzenie C++ o nowe rzeczy, ktore pozwalaja gładko pisac kod C++'o'podobny, ktory kompilator Visualowy potrafi skompilowac tak, aby wspolpracowal zarowno z natywnymi bibliotekami C++ jak i zarzadzanymi .Net'owymi. C++/CLI jest najsilniejszym pod wzgledem mozliwosci jezykiem z platformy .Net, ma najwierniejsze przelozenie na IL. oczywiscie c++/cli jest microsoft-only, jesli nie liczyc platformy MONO na linuksa ktora jest daleko w tyle i nawet nie jestem pewien czy kompilator c++/cli udostepnia.

0
quetzalcoatl napisał(a)
using namespace System.ComponentModel;   //o ile dobrze pamietam:)

[ComVisible(true)]     //TU
public ref class X {...}

.

Hmmm..

using namespace System::ComponentModel;
//using namespace System.ComponentModel;
[ComVisible(true)]  

dla obu przypadkow (ten gorny System::ComponentModel jest poprawny (przynajmniej kompilator tak zasugerowal).. wywala blad:

error C2337: 'ComVisible' : attribute not found

co tez MSDN tlumaczy jako (error C2337) :

You have used an attribute that is not supported in this version of Visual C++.

quetzalcoatl napisał(a)

...sprowadzaloby sie to do eksponowania w klasie jedynie rzeczy .Net'owych (czyli Int32, IntPtr, String (nie std::string!!), klasy ref itp..). Natywne c++'owe teez sie poniekad da.. ale jest bardzo bardzo duzo zabawy z tym.. albo przerob je na kolekcje z .net, albo samo eksponowane property przez ta klase zrob jako takowa kolekcje i synchronizuj (kopiuj dane z jednego w drugi i vice versa, tak aby byly zawsze spojne) ja z oryginalnym wektorem

Chwilka... musze to przetrawic na spokojnie (i z wujkiem google :) )..
ale czy to znaczy, ze w .NETcie jest pojemnik analogiczny to vectora (ktorego stosowalem, a ktory da sie bez problemow wyeksportowac do DLLki?

quetzalcoatl napisał(a)

C++/CLI jest INNYM JEZYKIEM PROGRAMOWANIA niz C++. jest to rozszerzenie C++ o nowe rzeczy, ktore pozwalaja gładko pisac kod C++'o'podobny, ktory kompilator Visualowy potrafi skompilowac tak, aby wspolpracowal zarowno z natywnymi bibliotekami C++ jak i zarzadzanymi .Net'owymi. C++/CLI jest najsilniejszym pod wzgledem mozliwosci jezykiem z platformy .Net, ma najwierniejsze przelozenie na IL. oczywiscie c++/cli jest microsoft-only, jesli nie liczyc platformy MONO na linuksa ktora jest daleko w tyle i nawet nie jestem pewien czy kompilator c++/cli udostepnia.

:)

czyli dzieki temu... moge dalej uzywac w programach std::cout... itp... nawet jezeli stosuje elementy stricte .NETowe (a bed emusial..).

http://pl.wikipedia.org/wiki/C%2B%2B/CLI (to co napisales + pogladowy przyklad..).

dzieki :)

0

poprawka, nie componentmodel a System::InteropServices

Robcio0909 napisał(a)

ale czy to znaczy, ze w .NETcie jest pojemnik analogiczny to vectora (ktorego stosowalem, a ktory da sie bez problemow wyeksportowac do DLLki? *)

tak, sa np. http://msdn.microsoft.com/en-us/library/system.collections.generic.aspx i tamtejsze List<typ> bedzie najblizsze vectorowi<typ>
*) DLLką to mozna eksponowac wszystko bez zadnego problemu.. problem w tym, ze to ma byc klasa widoczna w COM/VB/ !

Robcio0909 napisał(a)

czyli dzieki temu... moge dalej uzywac w programach std::cout... itp... nawet jezeli stosuje elementy stricte .NETowe (a bed emusial..)

dokaldnie tak

0
quetzalcoatl napisał(a)

poprawka, nie componentmodel a System::InteropServices

Hmmm, wszystko elegancko sie kompiluje, DLL'ka "zbudowana"... tylko ze w VB jak mojej funkcji nie bylo, tak nie ma... :/ (w trakcie kompilacji bledow ani warningow nie zauwazylem)..

PS: ten link do msdná jest swietny (tzn tresci tam zawarte)..

dobra, na spokojnie raz jeszcze od poczatku zrobie co mi poradziles (wlasna klasa do DLLki).. [bo to jest problem No1... jak to przejde, to zajme sie kontenerami... :) ]

...niestety.

Czy moglbym prosic o dzialajacy przyklad na eksport wlasnej klasy?? (mowa o projekcie typu classlibrary)
(analogicznej jak ta z przed kilku postow)

zastosowanie [ComVisible(true)] nie wnislo tutaj niczego nowego (:/ albo zle ja umiescilem.. [plik .h, tuz przed zdefiniowaniem klasy])...

Eksportowanie wlasnej klasy wydaje sie czyms powszechnym, niemniej nie udalo mi si eznalezc (innych niz te tutaj podane) wskazowek...

pozdrwiam,
jeszcze chwile poszukam i poprobuje a potem "chwila" przerwy..

0

okai.. mialem chwilke i sie przyjrzalem dokladnie temu co zamiesciles. Chodzilo dokladnie o to, o czym mowilem - argumenty i wartosci zwracane musza byc akceptowalne przez com/.Net'a..

to co u siebie probowales zrobic, to przekazanie obiektu zarzadzanego przez wartosc (ref class!).. nie jest to dozwolone, .Net tego "nie umie", wiec te metody zostaly pominiete.. ponizej przyklad pokazujacy co wolno a czego nie wolno:)

DLL:

// comvisible.h

#pragma once

using namespace System;

namespace test {

	public class klasa_nat
	{
	};

	public ref class klasa_ref
	{
	public: 
		bool metoda_1(klasa_nat metoda){return false;}
		Boolean metoda_2(klasa_nat metoda){return false;}

		bool metoda_3(klasa_ref metoda){return false;}
		Boolean metoda_4(klasa_ref metoda){return false;}

		bool metoda_5(klasa_nat* metoda){return false;}
		Boolean metoda_6(klasa_nat* metoda){return false;}

		bool metoda_7(klasa_ref^ metoda){return false;}
		Boolean metoda_8(klasa_ref^ metoda){return false;}
	};
}

VB:

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim x_nat As test.klasa_nat = New test.klasa_nat
        Dim x_ref As test.klasa_ref = New test.klasa_ref

        Dim wynik1 As Boolean = x_ref.metoda_1(x_nat)
        Dim wynik2 As Boolean = x_ref.metoda_2(x_nat)
        'Dim wynik3 As Boolean = x_ref.metoda_3   - nie widoczna
        'Dim wynika As Boolean = x_ref.metoda_4   - nie widoczna
        'Dim wynik5 As Boolean = x_ref.metoda_5   - nie widoczna
        'Dim wynik6 As Boolean = x_ref.metoda_6   - nie widoczna
        Dim wynik7 As Boolean = x_ref.metoda_7(x_ref)
        Dim wynik8 As Boolean = x_ref.metoda_8(x_ref)
    End Sub
End Class
0

quetzalcoatl naprawde ogromne dzieki :) [to dziaala :) i cieszy]

... wiec teraz siadam do programu i przerabiam vectory na listy...

:)

0

..w c++ wywolywalem argumenty/parametry poprzez referencje (&).... wiaodmo, oszczednosc czasu.. a dodatkowo zmienialem tez i parametry tak podawane..

..jak to zrobic w c++/CLI?

Kolejna rzecz, do tej pory uzywalem (w pracy z plikiem) rozwiazania z czystego C..

FILE * file1;
file1 = fopen(file_name.c_str(), "r");
...
fgets(line2, 512, file1);

bo to rozwiazanie bylo o wieeeele szybsze niz fstream i getline(linia, plik);

Jak z tym teraz przejsc do C++/CLI ?

I na koniec...
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=274 itd..

myslalem ze musze przepisac program na cos nowszego... i lepszego (bardziej uniwersalne) a tymczasem moze si eokazac, ze sie "laduje na mine"..? ( i wszystko dzialac bedzie.. a jak, ale wolniej)..

Rozumiem, ze aby moc wywalic DLLke dla uzytkownikow VB takie dzialanie jest konieczne (??)... no coz..

0

nie, nie jest konieczne. to co jest konieczne to wystawienie interface'u COM. obecnie najprosciej zrobic to w ten sposob, ale NIE jest to konieczne, mozna go tez wystawic przez czystego C++'a, ale to serio, nie wiem czy warto sie trudzic..

przekazanie przez referencje? heh.. ogladales ten przyklad co podalem? nie zauwazyles "klasa_ref" ? ów to "zarzadzany wskaznik", czyli taka ".netowa referencja". innego sposobu przekazywania parametrow zarzadzanych nie ma. przez wartosc/wskaznik/referencje - to tylko typy natywne [wiem, trywializuje, ale nie ma co..]

plik? pisz po staremu. to jest glowna (jedyna?:) zaleta c++/cli - ze mozesz pisac komplentnie po staremu i nowym wspomagac sie tylko tam gdzie potrzeba. i tak to wlasnie zrob! napisz sobie wszystko 'PO STAREMU', i jedynie metody ktore chcesz wystawic na zewnatrz zaopatrz w 'NOWE' typy zwracane i wartosci pobierane. nie musisz rezygnowac ze starych rzeczy, po prostu zadbaj o to zeby byly w srodku, a na zewnatrz wystawaly typy .net

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