CBuilder da DLL Sorunu

C, C++ ve C++ Builder ile ilgili konuları buraya yazabilirsiniz.
Cevapla
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1526
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

CBuilder da DLL Sorunu

Mesaj gönderen lazio »

merhabalar,
delphi de hazırlamış olduğum dll dosyasını CBuilder a nasıl gömebilirim.
aslında ben "Add to Project" seçeneği ile dll yi programa ekliyorum ve
boş bir *.cpp dosyası açıp fonksiyonları görünen tanımlarını ve dllimport yöntemi ile çağıracağımı yazıyorum. daha sonrada projedeki herhangi bir forum dosyasından çağırıyorum(tabii formun header ınada cpp dosyasını tanıtıyorum). işte tam bu noktada programı derlerken formun obj dosyası ile ilgili hata veriyor. unresolve export .... xx.obj gibi bişey..
benim yaptığım yanlışmı eksikmi..
teşekkürler..
Resim

..::|YeşilMavi|::..
Kullanıcı avatarı
warder
Üye
Mesajlar: 255
Kayıt: 10 Mar 2004 04:59

Mesaj gönderen warder »

Add to Project ile dll programa eklenmez.
dll yi kullanmanın yolları delphi de neyse builder de de aynı olmalı.
Yani dinamik veya statik. sanıyorum siz bunları zaten biliyorsunuz.
Amacınız statik kullanmaksa. Add to Project ile *.dll dosyasının aynı adlı *.lib dosyasını projeye eklemeniz gerekiyor. *.dll dosyasını system, system32, windows klasörlerinden birisinde ya da *.exe ile aynı klasörde bulundurmalısınız.
dinamik kullanmayı düşünüyorsanız herhengi bir şey eklemenize gerek yok
... Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!
Mustafa Kemal Atatürk...
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1526
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

merhaba,
normalde delphi de dll yi tanımlarken
function xxxx(); extern "dlladi.dll" gibi tanımlıyoruz.
ancak c de böyle bir olay yok bildiğim kadarıyla, ve böyle bir olay yoksa ilgili fonk. hangi dll nin içinde olduğunu nasıl anlatacağız. ayrıca dll yi delphi de yazdım yani elimde *.lib dosyası yok..
teşekkürler..
Resim

..::|YeşilMavi|::..
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

bilmiyorum ama c de bir dll deki fonksiyonu kullanmak icin header dosyanda fonksiyonların prototipini belirtmen lazım
bu da delphi de ki tanımlamanın bir benzeri olmalı
ÜŞENME,ERTELEME,VAZGEÇME
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1526
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

evet, bende bir header dosyasına fonksiyonları tanımlıyorum
extern __d... xxx(int) şeklinde
ama burada delphi deki gibi dll dosyasının adını yazamıyorum, yabi c deki kullanımı bu şekilde değil..
doğrusu nasıl bilemiyorum
Resim

..::|YeşilMavi|::..
Kullanıcı avatarı
warder
Üye
Mesajlar: 255
Kayıt: 10 Mar 2004 04:59

Mesaj gönderen warder »

lazio yazdı:merhaba,
normalde delphi de dll yi tanımlarken
function xxxx(); extern "dlladi.dll" gibi tanımlıyoruz.
ancak c de böyle bir olay yok bildiğim kadarıyla, ve böyle bir olay yoksa ilgili fonk. hangi dll nin içinde olduğunu nasıl anlatacağız. ayrıca dll yi delphi de yazdım yani elimde *.lib dosyası yok..
teşekkürler..
Mesajlarınızda dikkatimi çeken, konuyu fazla abarttığınız.
Tabii bu doğal hakkınız. Sadece aslında o kadar zor olmadığını vurgulamak istiyorum.
öncelikle *.lib dosyasını nasıl oluşturacaksınız:
builder/bin dizininde implib.exe var. lib dosyası yapacağınız dll yi bu dizine taşıdıktan sonra (istersen taşıma. ben kolayıma geleni öneriyorum)
komut satırında aynı dizine geldikten sonra aşağıdaki örneğe uygun olanı enterlayın.
C:\...vs.\vs.\ bin\implib istediğinizisim.lib dllninadı.dll
buradaki istediğinizisim.lib genelde dll ile aynı ad olarak kullanılır. adettendir.
böylece aynı dizinde *.lib dosyası da oluşur. Bu lib dosyasını Add to project ile eklemelisiniz.
dll dosyasında export ettiğiniz fonksiyonları şimdi import edip kullanabilirsiniz.
örnek export...

Kod: Tümünü seç


#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        return 1;
}
//---------------------------------------------------------------------------
  double  __export AsagiYuvarla(double sayi)
  {
       .....vs.vs.
       return sonuc;
  }
//---------------------------------------------------------------------------
  double  __export YukariYuvarla(double sayi)
  {
      ...vs.vs..
      return sonuc;
  }
//---------------------------------------------------------------------------  

örnek import:

Kod: Tümünü seç

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

double  __import AsagiYuvarla(double sayi);
double  __import YukariYuvarla(double sayi);

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
bir static dll kullanımı bundan ibaret.
... Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!
Mustafa Kemal Atatürk...
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1526
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

ilginize teşekkürler, deneyeceğim..
Resim

..::|YeşilMavi|::..
Kullanıcı avatarı
lazio
Moderator
Mesajlar: 1526
Kayıt: 11 Tem 2003 04:55
Konum: İstanbul

Mesaj gönderen lazio »

Kod: Tümünü seç

[Linker Error] Unresolved external 'BilgiOk(System::AnsiString)' referenced from G:\DLL_DENE\UNIT1.OBJ
bu mesaj ne anlama geliyor acaba :shock:

kullanmak istediğim dll yi tanımlıyorum..

Kod: Tümünü seç

TCevap __import BilgiOk(AnsiString msg);
sorun yok. derlediğimde hiçbir hata vermiyor..
ancak

Kod: Tümünü seç

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  BilgiOk("Deneme");
}
kullanmayı denediğimde derleme esnasında en başta belirttiğim bu hatayı veriyor..

Not: Lib dosyasını olşturup "Add File To Project" ile eklediğim halde..
Resim

..::|YeşilMavi|::..
Kullanıcı avatarı
warder
Üye
Mesajlar: 255
Kayıt: 10 Mar 2004 04:59

Mesaj gönderen warder »

Linker in dediği,
"Bana söylediğin yerde bundan birden fazla tanımlanmış, sen hangisinden bahsediyorsun anlayamadım." veya "bundan orada yok o yüzden çözemedim"
gibi bir mesaj. Yani kararsızlık durumu.
typedef hatalarına düşmüş olabilirsiniz. Kimbilir göremediğimiz yerlerde neler yaptınız. Bence bilmediğiniz veya tam emin olmadığınız cpp özelliklerinden yararlanmaya çalışmamalısınız. Sade ve ekonomik olmanız problemsiz sonuçlar almanıza yardımcı olabilir.
Ayrıca fonksiyondan dönen tipe bakarak (hoş tipin ne olduğu anlaşılmıyor ama) kullandığınız yerde void muamelesi yapmanız da tuhaf bir durum.
Bu şekliyle verecek başka cevap yok gibi.

ilave : .....
Sizin durumunuz kafama takıldı ve inceledim.
Sonuç olarak, kullandığınız fonksiyonu tanımladığınız header dosyasını include etmişsiniz. Bu yüzden hata almıyorsunuz. Ancak aynı fonksiyonun cpp dosyasını "Add file to project" ile eklememişsiniz. Yani ilgili fonksiyonun cpp dosyası eklenmediğinden obj dosyası oluşturulamıyor. Bu durumda header ını eklediğiniz için de kullanılamıyor. Linker include ettiğiniz dosyanın obj unuda arıyor ama orada zaten yok ve kararsızlığa düşüp projeyi bağlayamadığı için hatayı veriyor.
cpp dosyasını da belirttiğim gibi eklediğinizde problem durumu ortadan kalkacaktır.
... Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!
Mustafa Kemal Atatürk...
osC++CoDeR
Üye
Mesajlar: 2
Kayıt: 16 Mar 2008 04:09

Re: CBuilder da DLL Sorunu

Mesaj gönderen osC++CoDeR »

@lazio konu 2004 konusu şimdiye kadar çoktan aşmışsındır bu olayı. Mümkünse bana anlatabilirmisin..?
Bende C++ projemde delphi ile derlediğim dll leri kullanmak istiyorum.

Hatta başka bir konunda delphi pas dosyalarının C++ içinde kullanıldığından bahsetmişsin. bu konuda da araştırdım ama tatmin edici bir sonuç alamadım.
Aydınlatırsan memnun olurum.
AliCaNelKa
Üye
Mesajlar: 6
Kayıt: 04 Oca 2008 03:10
Konum: IstanbuL

Re: CBuilder da DLL Sorunu

Mesaj gönderen AliCaNelKa »

@osC++CoDeR Delphide yazılmış veya herhangi bir dilde yazılmış bir dll yi dinamik olarak şu şekilde kullanabilirsin Delphide örnek vermek gerekirse...

Bir msj procedürü yapalım ve export edelim...

Kod: Tümünü seç

Procedure msj(msj:String);Stdcall;Export;
begin
windows.MessageBox(0,pchar(msj),'bildiri',0);
end;
exports msj;
ve C++ Builderde bu dll i çağıralım.
ilk olarak proceduru tanımlıyoruz...

Kod: Tümünü seç

typedef HINSTANCE( __stdcall *dll ) ( LPCTSTR );
dll fmsj;
ve Dll i çağıralım...

Kod: Tümünü seç

HMODULE hmsj =LoadLibrary("Project2.dll"); // delphide derlenen dllmiz
fmsj=(dll) GetProcAddress(hmsj,"msj"); 
fmsj("dll msj");
ve C++ Builder de hazırladığımız kodları derleyelim...
Kullanıcı avatarı
SHURZAN
Üye
Mesajlar: 73
Kayıt: 06 Eki 2007 05:34
Konum: İstanbul

Re: CBuilder da DLL Sorunu

Mesaj gönderen SHURZAN »

Forumu gezerken gördüm konu çok eski olmasına rağmen hala çözümlenmemiş olmasından dolayı cevap yazma gereği duydum.

Sizde biliyorsunuz ki DLL ler projenize dinamik ya da statik olarak bağlanabilir. Statik bağlanmasında derleme aşamasında fonksiyonların dll içindeki imzasına denk gelen haritalandırma için gerekli. Ancak genede fonksiyonların porototiplerini derleyiciye bildirmeniz gerekir yoksa derleyi sadece lib dosyasına bakarak bildirim yapmış saymaz.

Bir de bildiğiniz gibi dinamik bağlama ile dll dosyalarınızı çalışma zamanı bağlayabilirsiniz yani her ikisi de delphide olduğu gibidir sadece söz dizimi farklı.

Statik bağlamada lib dosyasına ihtiyacımız vardır eğer elimizde dll dosyasının lib dosyası yoksa warder'in açıkladığı gibi borland'ın implib.exe uygılamasını kullanarak lib dosyası oluşturabilir ve projende static bağlantıyla sorunsuz kullanılabilir. dll nin olduğu dizinine komut satırıyla erişilir ve komut satrına şu komut yazılarak

Kod: Tümünü seç

C:\MyDLL>implib.exe mydll.lib mydll.dll
lib dosyası elde edilir. bu lib dosyası ya elle doğrudan projeye dahil deilir ya da kod satırıyla

Kod: Tümünü seç

#pragma link "Mydll.lib"
projeye eklenebilir ancak lib dosyasının proje dizinin olması unutulmamalı.

DLL dosyamızda kullanacağımız fonksiyonların deklerasyonu C söz dizimine uygun yazılmazsa derleme aşamasında ya da çalışma zamanında link hatası alınabilir.
Deleyicimize deklerasyonda şunları diyoruz bu fonksiyon harici bir bağlantıdır(extern) sen bulacaksın nerede olduğunu, Söz dizimi C dir ve bu bir dll fonksiyonudur şöyleki;

Kod: Tümünü seç

extern "C" __declspec(dllimport) int toplamafonksiyonum(int birinci, int ikinci);
Bu bir bildirimdir "int toplamafonksiyonum(int birinci, int ikinci)" toplamafonksiyonum iki tamsayı parametre alır ve işlevini yaptıktan sonra sonucunu tamsayı olarak döndürür.

Artık bu fonksiyonumuzu istediğimiz zaman çağırır kullanabiliriz.

Kod: Tümünü seç

ShowMessage( toplamafonksiyonum(StrToInt(Edidt1->Text), StrToInt(Edit2->Text)  );
DLL dosyamızda bir kaç fonksiyondan fazla ise dll'nin import edilişini define edebilirzi böylece her bildirim satırında uzun uzun yazmaktanda kurtulabiliriz.
öneğin

Kod: Tümünü seç

extern "C" __declspec(dllimport) int toplamafonksiyonum(int birinci, int ikinci);
extern "C" __declspec(dllimport) double bolmefonksiyonum(int birinci, int ikinci);
extern "C" __declspec(dllimport) int cikartmafonksiyonum(int birinci, int ikinci);

/*.....
......
.....
*/
belkide 15. satırda gene bildirim...
ancak satırın şu kısmını tanımlanmamışsa tanımlatabiliriz(define) edebiliriz extern "C" __declspec(dllimport)

Kod: Tümünü seç

ifndef DllImport
#define DllImport extern "C" __declspec(dllimport)
#endif

DllImport int toplamafonksiyonum(int birinci, int ikinci);
DllImport double bolmefonksiyonum(int birinci, int ikinci);
DllImport int cikartmafonksiyonum(int birinci, int ikinci);
/*............
............
...*/

DLL dosyamız hazırlanırken;
Hangi fonksiyonumuz dış bağlantıya açıksa onuda fonksiyonumuzun deklarsayonunda, sadece tamınlama yapılmısa tanımında bu fonksiyon dış bağlantıya açıktır bildirimi vermeliyiz.

Kod: Tümünü seç

//dll içindeki fonksiyonumuz...

extern "C" __declspec(dllexport) int toplamafonksiyonum(int birinci, int ikinci)
{
 return birinci+ikinci;
}

Konuyla ilgilenenler için sanırım yeterince açıklayıcı olmuştur.
Başarılar (Yaşar)
En son SHURZAN tarafından 10 Haz 2010 06:53 tarihinde düzenlendi, toplamda 2 kere düzenlendi.
Cevapla