Autor Wątek: Po awarii dysku program nie wczytuje DLLki  (Przeczytany 2377 razy)

Offline Frondeus

  • Użytkownik

# Lipiec 25, 2010, 11:50:17
Mam dziwny problem. Niedawno miałem awarie dysku twardego (odłączył się od płyty głównej). OD tego czasu mój program nie wczytuje dllek. Inne moje programy też. Dllki też są robione przeze mnie. Dlatego mam pytanie : Co może być problemem? (kod programu i dllki właściwie nie ruszany a dllka NA PEWNO jest w katalogu) .

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Karol

  • Użytkownik

# Lipiec 25, 2010, 13:05:19
Może nie może odczytać tej dllki? Sprawdzałeś czy nie ma błędów na dysku i czy tą dllkę możesz choćby podejrzeć w jakimś hex viewerze?

Offline Frondeus

  • Użytkownik

# Lipiec 25, 2010, 14:28:43
Nawet jak przekompiluje od nowa i podmienie ta dllke ?
Dllka jest pusta , czysty szablon z msvc2010.
Zeby nie bylo:
#include <Windows.h>
#include <conio.h>
#include <iostream>
using namespace std;

HMODULE hDll;
int LoadDll()
{
hDll = LoadLibrary ((LPCWSTR)"Core.dll");
if (hDll == NULL)
{
cout << "Error: Nie można załadować biblioteki Core.dll" << endl;

return 0;
}
}


void main()
{
LoadDll();
_getch();
}
To był program ładujący . Zero skomplikowania.
A dll'ka jak już mówiłem : pusty szablon z kreatora.
Zmiana duzyc liter na małe, usuniecie ".dll" itp nie pomaga
« Ostatnia zmiana: Lipiec 25, 2010, 14:33:26 wysłana przez Frondeus »

Offline Rolek

  • Użytkownik

# Lipiec 25, 2010, 14:44:25
(LPCWSTR)"Core.dll"
Zastanawiałeś się kiedyś czym różni się wchar_t od char?

PS: http://www.warsztat.gd/articles.php?x=view&id=270
« Ostatnia zmiana: Lipiec 25, 2010, 14:47:21 wysłana przez Rolek »

Offline Frondeus

  • Użytkownik

# Lipiec 25, 2010, 14:55:31
haha. Działa choć nie mam pojęcia czemu wcześniej (przed awaria) działało skoro nie powinno ;)

edit: Juz podlacze sie do tematu w sprawie dllek .Z tego co wyczytalem na Dark Cult 2.0 Moge zrobić export klasy tworząc np takie coś:
extern "C"
{
__declspec (dllexport) Graph::Render* GetRender();

}
Wszystko działa dobrze do czasu gdy chce wywołać w kodzie programu metode:
GetRender()->Init();
Według artykułu powinno zadziałać.
lecz dostaje błąd linkera:
public: void __thiscall Graph::Render::Init(void)" (?Init@Render@Graph@@QAEXXZ) referenced in function _main
Czy to oznacza że muszę jeszcze dołączać plik cpp? Oprócz:

#include "..\Graph\Graph.h"
#pragma comment(lib,"Graph.lib")
?
« Ostatnia zmiana: Lipiec 25, 2010, 15:58:57 wysłana przez Frondeus »

Offline Rolek

  • Użytkownik

# Lipiec 25, 2010, 16:26:06
Nie wyeksportowałeś metody Init()

Offline Frondeus

  • Użytkownik

# Lipiec 25, 2010, 16:35:17
Tego na drak culcie nie bylo :P Wyeksportuje i zobacze...
Dzięki  kolego . Wszystko działa jak należy :)

Offline Rolek

  • Użytkownik

# Lipiec 25, 2010, 16:38:59
Przy zapakowywaniu klas w dll dobrze jest mieć wydzielony interface.
foo.h do dll i exe
Kod: (cpp) [Zaznacz]
class IFoo
{
public:
virtual void set(int) = 0;
virtual int get() = 0;
virtual ~IFoo() = 0;
};
foo.cpp do dll
Kod: (cpp) [Zaznacz]
class CFoo : public IFoo
{
int x;
public:
CFoo(int n) : x(n) {}
int get() { return x; }
void set(int n) { x = n; }
~CFoo() {}
};

extern "C" __declspec(dllexport) IFoo* CreateFoo(int n) { return new CFoo(n); }
extern "C" __declspec(dllexport) void DeleteFoo(IFoo* p) { delete p; }

Offline Frondeus

  • Użytkownik

# Lipiec 26, 2010, 13:17:10
Hmm ciekawe. A co jeśli klasa przechowywałaby np.
taki wskaźnik?:
IDirect3D9* pD3D;
czy wtedy tak by to wyglądało?
class IFoo
{
public:
virtual [i co tu dać?] get() = 0;
};
class CFoo : public IFoo
{
        IDirect3D9* pD3D;
public:

IDirect3D9* get() { return pD3D; }
};
 
extern "C" __declspec(dllexport) IFoo* CreateFoo(int n) { return new CFoo(n); }
extern "C" __declspec(dllexport) void DeleteFoo(IFoo* p) { delete p; }

Narazie nie mam interfacu tylko tworze plik h z deklaracją a w cpp. implementacje.
potem includuje taki plik h w projekcie gdzie chce użyć dllki.

Lecz zastanawiam się jak zrobić w przypadku importu takiej np do C# (co mnie interesuje ze względu ze w dll'ce zamierzam trzymać Render,w c++ napisać grę, a w c# napisać edytor)...
Oczywiście mógłbym napisać edytor w c++ ale wtedy mam opcje:
-Winapi (do zaawasowanego edytora raczej sie nie nadaje)
-Windows Forms  - to jest C++/CLI więc też będzie problem.
-Qt - Ciekawe ale co z komercją?
-WxWidgets - próbowałem ale coś nie zabardzo umiem dopasować tą bibliotekę aby działała z msvc..
-GTK+ - tego w ogóle nie ruszałem
-C# - no tu jest problem z deklaracjami. Jeśli byłyby to zwykłe metody nie zwracające np wskaźnika na klasy to działałoby bez problemu, no ale nie o to mi chodzi... chyba że napisze całość edytora w C++ i wpakuje do drugiej dllki po czym bede uruchamiać tylko takie funkcje a wynik zwracać w jakiś pokręconych intach(czytaj : w typach podstawowych) ;)

Załóżmy że oleje wszystko i wybiore QT. Czy mogę zbudować na nim edytor (licencja darmowa) , za pomocą edytora stwrozyc mapki, mapki dać do gry i sprzedawać? Czy to JAK stworze mapki ma znaczenie?
« Ostatnia zmiana: Lipiec 26, 2010, 14:00:08 wysłana przez Frondeus »

Offline vashpan

  • Użytkownik
    • Strona

# Lipiec 26, 2010, 14:59:29
Wydaje mi sie ze licencja jest na biblioteke a nie uzycie tego co sie stworzy softem stworzonym za pomoca tej biblioteki ;) Ale w USA tego typu prawo jest "dziwne", wiec kto wie...

A co do C#, nie wystarczy ci dllka ;) Assembly z .NET to cos innego niz "prawdziwa" biblioteka DLL, tam DLL to w zasadzie kontener dla kodu zarzadzanego, a jest w formacie/kontenerze PE tylko dla wygody uzycia i po to zeby nie wprowadzac jakis nowych formatow/rozszerzen do Windowsa, dzieki temu i mozliwosci wpakowania takze natywnego kodu "odpalajacego" do .exe'kow, aplikacje .NET "wygladaja" na zwyczajne aplikacje, w odroznieniu od np. Javy i jej "jarow"...

Zeby uzywac twojego silnika w .NET najlatwiej pewnie byloby stworzyc prosty wrapper w C++/CLI , ktory w zasadzie do tego zostal stworzony...

Offline Frondeus

  • Użytkownik

# Lipiec 26, 2010, 15:24:38
C++/CLI ? A może właśnie w Windows Forms Aplication? Właściwie to zależy mi na dobrej obsłudze GUI takiej jaka jest w C++/CLI poprzez WFA czy też w C#.
Hmm muszę się jeszcze pouczyć jak właśnie łączyć taki kod .NET z c++.

Offline vashpan

  • Użytkownik
    • Strona

# Lipiec 26, 2010, 16:16:59
C++/CLI to .NET'owa wersja C++, sluzy wlasnie jako klej kodu natywnego z zarzadzanym, bo jest to wygodniejsze niz robienie tego z poziomu C# ( choc tez w niektorych prostych przypadkach i funkcji z C sie da ( Marshalling ) ) Windows Forms nie ma tutaj nic do rzeczy, to po prostu czesc .NET Framework i mozna jej uzywac tak samo z poziomu C++/CLI jak i C# tyle ze C# jest wygodniejsze...

Offline Frondeus

  • Użytkownik

# Lipiec 26, 2010, 22:09:05
Korzystając z Twoich rad oraz http://msdn.microsoft.com/en-us/library/26thfadc.aspx napisałem taki kod:
#include "..\Graph\CLI\Graph.h"
#pragma comment(lib,"Graph.lib")
 

using namespace System;
using namespace System::Runtime::InteropServices;

 
 class Loader
 {
 public:

[DllImport("graph.dll", CharSet = CharSet::Unicode, SetLastError = false)]
Graph::Render* GetRender(void);
 };

 }
 int main(array<System::String ^> ^args)
 {
     Loader loader;
     loader.GetRender();
     return 0;
 }
Jednak nie rozumiem  jak tu użyć extern "C" aby nie wyświetlało http://msdn.microsoft.com/en-us/library/0htdy0k3.aspx ...

Próbowałem kilku wariantów jak ten:
extern "C"
 {
 Graph::Render* GetRender()
 {
     Loader l;
     return l.GetRender();
 }
 }
 int main(array<System::String ^> ^args)
 {
     GetRender();
     return 0;
 }
Lecz albo nadal dostawałem błąd albo nieprawidłowo zagnieżdżałem owy feralny extern...
« Ostatnia zmiana: Lipiec 26, 2010, 22:11:59 wysłana przez Frondeus »

Offline Frondeus

  • Użytkownik

# Lipiec 27, 2010, 13:42:25
Sorry za double posta ale si pogubilem do reszty...
Skoro ten kod nie działa, to czemu po dodaniu linijki :
Tworzy mi okno? nie używam do niej żadnego pinvoke, nic z tych rzeczy....

Właściwie to wszystko gotowe, dzięki za rady itp.
« Ostatnia zmiana: Lipiec 28, 2010, 14:00:56 wysłana przez Frondeus »