.NET dll delphi 7-ben

.NET dll delphi 7-ben
2013-03-27T08:45:46+01:00
2013-03-30T18:06:43+01:00
2022-11-28T16:15:41+01:00
stY
Sziasztok!

Most csinálok ilyet először, hogy szükségem lenne egy saját .NET C# -ban megírt dll használatára egy szintén saját delphi programban.

Utána olvastam a neten, szerintem egy hajszálnyira vagyok a megoldástól.

A .net alkalmazás egy sima console application, egyszerűség kedvéért legyen ennyire egyszerű most:


//Program.cs-ben: static void Main(string[] args) { new Osszeado(5, 10, "Hello"); } Az oszály pedig: class Osszeado { public Osszeado(int a, int b, string uzenet) { System.IO.StreamWriter file = new System.IO.StreamWriter("proba.txt"); file.WriteLine(eredmeny(a, b).ToString() + " " + uzenet); file.Close(); } private int eredmeny(int a, int b) { return a + b; } }

Ez fileba ír nekem próbaképp dolgokat, hogy delphiből ellenőrizhessem majd, hogy megtörtén a fgv hívás.

- A properties -ben beállítottam, hogy class library forduljon belőle.

- Ezután a RegAsm-el sikeresen fordítottam belőle egy TypeLib.tlb -t.

Tehát van egy ProbaDll.dll

- A Delphiben a Project/Import type library alatt Add-al hozzáadtam a tlb-t és rányomtam,hogy Create unit.

Csinált nekem egy ilyet: TypeLib.tlb


unit ProbaDll_TLB; // ************************************************************************ // // WARNING // ------- // The types declared in this file were generated from data read from a // Type Library. If this type library is explicitly or indirectly (via // another type library referring to this type library) re-imported, or the // 'Refresh' command of the Type Library Editor activated while editing the // Type Library, the contents of this file will be regenerated and all // manual modifications will be lost. // ************************************************************************ // // PASTLWTR : 1.2 // File generated on 2013.03.27. 8:36:41 from Type Library described below. // ************************************************************************ // // Type Lib: D:\PROGRAMOZAS\Delphi\dllhivasaDelphivel\TypeLib.tlb (1) // LIBID: {A9873D4D-25B1-4C6E-A03A-2C7A0C67E747} // LCID: 0 // Helpfile: // HelpString: // DepndLst: // (1) v2.0 stdole, (C:\Windows\SysWOW64\stdole2.tlb) // ************************************************************************ // // *************************************************************************// // NOTE: // Items guarded by $IFDEF_LIVE_SERVER_AT_DESIGN_TIME are used by properties // which return objects that may need to be explicitly created via a function // call prior to any access via the property. These items have been disabled // in order to prevent accidental use from within the object inspector. You // may enable them by defining LIVE_SERVER_AT_DESIGN_TIME or by selectively // removing them from the $IFDEF blocks. However, such items must still be // programmatically created via a method of the appropriate CoClass before // they can be used. {$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers. {$WARN SYMBOL_PLATFORM OFF} {$WRITEABLECONST ON} {$VARPROPSETTER ON} interface uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants; // *********************************************************************// // GUIDS declared in the TypeLibrary. Following prefixes are used: // Type Libraries : LIBID_xxxx // CoClasses : CLASS_xxxx // DISPInterfaces : DIID_xxxx // Non-DISP interfaces: IID_xxxx // *********************************************************************// const // TypeLibrary Major and minor versions ProbaDllMajorVersion = 1; ProbaDllMinorVersion = 0; LIBID_ProbaDll: TGUID = '{A9873D4D-25B1-4C6E-A03A-2C7A0C67E747}'; implementation uses ComObj; end.


Most jön az a rész ahol elakadtam.
Olvastam, hogy alul a uses-ba, ahol a uses ComObj; van, ott még hozzá kellene vennem azt is, hogy uses ComObj,ProbaDll.

Fordításkor panaszkodik a delphi program, hogy ProbaDll.dcu not found. A dll és a typelib is ott van az (amúgy ha a usesből kihagyom a dll-em) forduló exe mellett.

Ha ez mind működne, egyszerűen elérném az Osszeado class-t? Mir rontok el?
Mutasd a teljes hozzászólást!
NA megtaláltam a hibát, minden tökéletesen működik:


intfRef := CreateComObject(CLASS_ExampleFunctions) as IExampleFunctions; result := intfRef.Add(StrToInt(a.Text), StrToInt(b.Text)); ShowMessage(Inttostr(result));

Nem csupán Examplefunctions kell a CreateComObject-en belül, kell elés a CLASS_ is....
Ezt jobban kiemelhették volna

Köszi a segítséget, de 2 napos szenvedés után csak meglett a megoldás...
Mutasd a teljes hozzászólást!

  • Kicsit módosítottam a dolgon közben, csináltam egy interface-t:


    public interface OsszeadoInterf { int eredmeny(int a, int b); }

    A class pedig:

    [ClassInterface(ClassInterfaceType.None)] public class Osszeado : OsszeadoInterf { public Osszeado() { } public int eredmeny(int a, int b) { return a + b; } }

    Delphi oldalon pedig a fő unitban : uses ComObj,ProbaDll_TLB;

    Eddig nem is szól.

    Próbálom deklarálni a

    proba:OsszeadoInterf;

    De nem találja....
    Mutasd a teljes hozzászólást!
  • Ok, [assembly: ComVisible(true)] -t beállítottam, így elérem a fgv-em delphiből a következő képpen:


    proba := CreateComObject(Osszeado) as OsszeadoInterf; ShowMessage(InttoStr(proba.eredmeny(10,4)));

    Már csak egy baj van. AMikor lefut, kiírja, hogy az osztály nincs gregisztrálva, pedig a regisztráció is:


    C:\Windows\Microsoft.NET\Framework\v4.0.30319>RegAsm d:\PROGRAMOZAS\Delphi\dllhi
    vasaDelphivel\ProbaDll.dll /regfile:ProbaDll.reg
    Microsoft (R) .NET Framework Assembly Registration Utility 4.0.30319.1
    Copyright (C) Microsoft Corporation 1998-2004. All rights reserved.

    Registry script 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\ProbaDll.reg' gen
    erated successfully

    látható módon sikeresen lefutott. És a regfiet felhasználva regisztráltam is ....
    Mutasd a teljes hozzászólást!
  • Nem tudom mi lehet, már mindennel próbálkoztam
    Delphi felismeri a dll-em, le is fordul a project, de a futáskor kiír egy üzenetet, hogy az osztály nincs regisztrálva.

    Próbáltam már RegAsm-el regisztrálni a dll-t. Azt írta sikeres.
    Próbáltam úgy is, hogy RegAsm-el egy reg file-t készítek és úgy is beregisztráltam, így sem jó.

    Próbáltam a gacutil /i ProbaDll.dll lefuttatni, ez is azt írja, hogy Assembly succesfully added to the cache. (Ehhez kellett a strong name használata, amihez sn -el kulcsot is generáltam, ez is szépen belement a dll-be)

    Próbáltam a regsvr32 ProbaDll.dll -el is beregisztrálni, ez is megcsinálja mégsem jó.

    Ötletem sincsen már. Nincs senki másnak sem ötlete? Nem magamnak tettem fel ezt a kérdést
    Mutasd a teljes hozzászólást!
  • Szia, ezeket én is megtaláltam.

    Amiket belinkeltél, ott még csak a dll használatot taglalja.Valóban egyszerű leírások, de nekem nem ez kell. Nekem a dll felhasználásával programszinten már nincsen gondom, annyi a gond csak, hogy nem tudom beregisztrálni. Az előző hozzászólásomban taglalt mind a 4 esetetet próbáltam, egyik sem hozta meg a sikert.

    Azért köszönöm a segítséget.
    Mutasd a teljes hozzászólást!
  • Nekem úgy tűnik, jól csinálod, akkor pedig nem marad más hátra - új project és kezdd elölről. Ne a sajátodat használd, próbáld meg az egyik mintát végrehajtani.

    A -os blog nagyon szépen leírja, hogy kéne működnie, ha ez így nálad nem működik, valami helyi problémád van.

    Ellenőrizd, hogy az assembly-d valóban ott van a GAC-ban!

    Nem lehet, hogy valamilyen jogosultság probléma szól közbe? Bár elvileg akkor azt kiírná... Ha lehet, tiszta új környezetben is teszteld (virtuális gép).

    Itt felhívják arra is a figyelmet, hogy egy könyvtárban kell lennie a Delphi exe-nek és a C# assembly-nek. Megerősítik itt is, hogy ennek így működnie kéne.

    Sajnos én nem értek Delphi-hez, úgyhogy közvetlenül nem tudom neked tesztelni.
    Mutasd a teljes hozzászólást!
  • Most megnéztem, a ProbaDll.dll-em bent van a
    C:\Windows\Microsoft.NET\assembly\GAC_32\ProbaDll\v4.0_4.0.0.0__afb3ede75b368d04

    mappába, tehát a gacutil /i ProbaDll.dll parancs be is tette a helyyére, nem csak az üzenet szerint.

    Még azon gondolkozok, hogy nem e a GAC_64 mappába kellene valahogy betenni. Tehát oda beregisztrálni.

    64 bites a windows 7-em. Viszont a dll-t 32 bitesre fordítottam, eszerint a 32-es mappában a helye (szerintem).
    Mutasd a teljes hozzászólást!
  • Őszintén szólva nem teljesen értem, miért kéne egyáltalán az assembly-t a GAC-ba tenni, ha úgyis azonos könyvtárban kell utána lennie. Tehát nem vagyok meggyőződve, hogy ez a lépés egyáltalán szükséges.

    Nézd meg a fenti linket, amit adtam! Az ottani leírásban egyáltalán nincs ez a lépés, mégis működik.

    Próbáld ki azt először, ne a saját projecteddel szenvedj! Majd ha van egy működő, minimalista referenciád, utána keresd a hibát a végleges projectben!

    Mindenképpen figyelj arra, hogy a megfelelő .NET runtime-hoz való regasm-et használd!

    (szerk.)
    Mutasd a teljes hozzászólást!
  • Igen, de kétségbe esve már mindennel próbálkozok. VAlahol írták, hogy ez is szükséges... Mondjuk azt én sem értem miért kellene ez, ha a dll úgy is ott van a delphi exe mellett...

    Nem tudom mi lehet a gond. Már virtuális Xp-n is próbálkoztam. Átvittem a delphi exe-t, a dll-t, és generáltam egy regfilet a RegAsm-el, hogy ott is tudjam tesztelni. Ott is bekerült a registry-be, és ott is ezt az osztályos üzenetet dobja...


    Valaki azt írta, hogy az AssemblyInfo.cs-ben a

    [assembly: Guid("a9873d4d-25b1-4c6e-a03a-2c7a0c67e747")] guidnak meg kellene, hogy egyezzen a registry-ben levő értékkel. Ami meg nálam {5D7EE26A-21A9-30EA-9F39-D04B40F99F68}.. Látható, hogy teljesen más.

    Más is írt hasonló problémát, de ott sem volt rá megoldás. Lehet, hogy nem is kell, hogy egyezzenek, nem tudom.

    Szerk.: A .NET 4 32 bites RegAsm-jét használom. Másik(64) el sem fogadja, beszól, hogy nem megfelelő dll, vagy nem is dll.
    Mutasd a teljes hozzászólást!
  • Dőlj hátra, nyugodj meg, ez egy ilyen szakma. A kapkodás nem visz előbbre.

    Megcsináltad az elejétől, csupa üres projectből a linken található minimalista példát (SimpleDLL)? Se GUID, se GAC nincs benne. Milyen eredménnyel?

    A regasm-et próbáld a Visual Studio Command Prompt-ból futtatni, az mindenképpen a jó verziót kell, hogy használja. Nem hiszem, hogy ez a gond, szerintem jót futtatsz, de egy hibát kizárunk.

    (szerk.)
    Mutasd a teljes hozzászólást!
  • Délután kipróbálom és majd írok. Most munkahelyen vagyok, ezt a dll-es hülyéskedést saját magam szórakoztatására csinálom egyelőre.

    A cél az lenne, hogy a delphi program ne külső console alkalmazást hívjon egy bonyolult művelet elvégzésére, hanem a dll-t használja majd. .NET-ben lett megírva a program ezen része, mert sokkal gyorsabban lefut linq stb. használatával , mint Delphiben.

    De majd du. kipróbálom és jelentkezem
    Mutasd a teljes hozzászólást!
  • Megcsináltam 0-ról a példa projektet, ahogy írják, a visual stúdioból fordítottam tlb-t is a "Register for COM interop" opciót bepipálva. Itt is ugyanaz az üzenet fogad:

    Képfeltöltés.hu - korlátlan ingyen tárhely képeidnek, regisztráció nélkül
    Mutasd a teljes hozzászólást!
  • Nézd csak ezt!

    Kellhet a regasm híváskor a /codebase kapcsoló (ez akkor kell, ha nem használod a GAC-ot).

    A ComVisible True-ra lett állítva a Properties/AssemblyInfo.cs-ben? Ha erre van, akkor nem kell a GUID attribútum, viszont szükséges a regisztrációhoz.

    (szerk.)
    Mutasd a teljes hozzászólást!
  • Kipróbáltam, és ezt írta ki:


    D:\PROGRAMOZAS\Delphi\dllhivasaDelphivel2>RegAsm /tlb /codebase TesztDll.dll Microsoft (R) .NET Framework Assembly Registration Utility 4.0.30319.1 Copyright (C) Microsoft Corporation 1998-2004. All rights reserved. RegAsm : warning RA0000 : Registering an unsigned assembly with /codebase can ca use your assembly to interfere with other applications that may be installed on the same computer. The /codebase switch is intended to be used only with signed assemblies. Please give your assembly a strong name and re-register it. Types registered successfully Assembly exported to 'D:\PROGRAMOZAS\Delphi\dllhivasaFelphivel2\TesztDll.tlb', a nd the type library was registered successfully

    Tehát sikeres, csak dobott egy warningot, de továbbra sem jó a delphi-s progi.

    Láttam, hogy az általad adott linken nem így csinálták az osztályt:


    [ClassInterface(ClassInterfaceType.None)] public class ExampleFunctions : IExampleFunctions { public int Add(int arg1, int arg2) { return arg1 + arg2; } }

    Hanem így:


    [Guid("d38a0d1a-1be3-4fa2-8f7f-65598e2d661e")] [ComVisible(true)] public class ExampleFunctions : IExampleFunctions { public int Add(int arg1, int arg2) { return arg1 + arg2; } }

    Így viszont visualstudioból le sem tudtam fordítani a dll-t.
    Amúgy meg az assemblyinfo.cs-ben ugy is alapból benne van a guid, meg a comVisible is, szóval ide fölösleges.

    Kipróbálom megint a string name használatát.
    Mutasd a teljes hozzászólást!
  • Na megcsináltam a strongname-t, generáltam neki egy kulcsot az sn -k Kulcs.snk parancsal és az AssemblyInfo.cs-ben
    [assembly: AssemblyKeyFile(@"D:\PROGRAMOZAS\Delphi\dllhivasaDelphivel2\Kulcs.snk")] meghivatkoztam


    Így a codebase-es kapcsolóval is szépen lefutott a RegAsm és ki is írta, hogy succesfull, de Delphiben még mindig nem jó.
    Mutasd a teljes hozzászólást!
  • Én nem a Class elé tenném a Guid és a ComVisible(true) attribútumokat, hanem az AssemblyInfo-ba, és csak oda.

    Ha bekapcsolom a Register for COM interop-ot, akkor nekem már próbálja is regisztrálni fordításkor és panaszkodik, hogy nincs joga registry-t írni.
    Mutasd a teljes hozzászólást!
  • Ezaz, hogy nekem is regisztrálja már fordításkor, mert látom, hogy a registry-be be is kerül.... Mégsem jó valami

    Én is cska az Assembly info-ba tettem az attribútumokat.
    Mutasd a teljes hozzászólást!
  • Igen, ha nem írod alá, akkor ki lehetne cserélni egy másik, azonos nevű assembly-re, ez a Warning csak erről szól.
    Mutasd a teljes hozzászólást!
  • Igen, ezért csináltam hozzá kulcsot. Szerintem már mindennek menni kellene :/
    Mutasd a teljes hozzászólást!
  • Próbáld meg egy frissen telepített gépen (elég a .NET Framework, nem kell sem VS, sem Delphi) regisztrálni... Ennek így működnie kéne.

    Ebben a bejegyzésben ott egy minta, hogy kell a regisztrációhoz szükséges .reg file-t generálni.
    Mutasd a teljes hozzászólást!
  • Van egy frissen telepített Virtuális Xp-m. Azon tényleg semmi nincs, csak a .Net 4, meg ez a program most.

    csináltam egy regfilet:

    RegAsm /codebase TesztDll.dll /regfile:Install.reg

    Ezt lefuttattam az Xp-n. Elindítottam a Delphi programot és ott is ugyanez a helyzet. Nem értem egyszerűen Az ilyen problémáknak általában valami nagyon egyszerű oka van Csak jó lenne rájönni.
    Mutasd a teljes hozzászólást!
  • Ez

    [ClassInterface(ClassInterfaceType.None)]

    az attribútum ott van a class előtt, ugye?

    Egy könyvtárban van minden file a végén, ugye?

    Mutasd a teljes hozzászólást!
  • Igen A teszt Xp-n is szépen létrejött a registry bejegyzés a reg file segítségével, leellenőrzitem.
    Mutasd a teljes hozzászólást!
  • Találtam egy elég részletes leírást, hogyan működik ez, érdekes, hogy itt külön GUID-ja van az interface-nek és a class-nak. Ez új...

    A class id kerül a HKEY_CLASSES_ROOT\CLSID-hez, az interface id kerül a HKEY_CLASSES_ROOT\Interface-hez.

    Érdekes...
    Mutasd a teljes hozzászólást!
  • Még egy lehetséges hibalehetőség, 64 bites rendszerek esetén. Ezt nézted?
    Mutasd a teljes hozzászólást!
  • Így is kipróbáltam, és még mindig változatlan. A 64 bitest megnézem mindjárt.
    Mutasd a teljes hozzászólást!
  • Még egy buktató: kell lennie egy public default konstruktornak.

    Nagy találmány ez a COM...
    Mutasd a teljes hozzászólást!
  • Az én dll-em a 64-es RegAsm-el le se tudom fordítani, mert kiírja, hogy not a valid .NET Assembly. (Azt x86-ra fordítottam).Bár az oprendszerem 64 bites. Ezt próbáltam.
    Mutasd a teljes hozzászólást!
  • Most csináltam egy default contructort.

    De még egy dolgot észrevettem. Delphiben mikor adom hozzá a type library-t, akkor zárójelben még mindig 1.0-t mutat, amikor az én assemblym már rég 5.0-nál jár.

    Mintha nem frissítené, pedig amit betallózok az mindig a legfrissebb.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd