[Delphi] DLL naar C# gaat om Handler

Pagina: 1
Acties:
  • 504 views sinds 30-01-2008
  • Reageer

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ok ik heb het volgende stukje Delphi code. In dit stukje gebruiken ze een DLL die ik moet implementeren in C#. Het probleem is dat ik in C# die handler niet goed krijg.

Eerst het stukje Delphi code

Benodigde declaraties
Delphi:
1
2
3
4
5
6
const DLLNAME = 'JL_VisionLib_DLL.dll';

function JL_Execute  (cmd: PChar; answer: PChar; maxSizeAnswer: integer): integer; cdecl; external DLLNAME;
function JL_GetImage (imageName: PChar; answer: PChar; maxSizeAnswer: integer): THANDLE; cdecl; external DLLNAME;
function JL_SetImage (imageName: PChar; imagetype: PChar; bmpH : THandle; answer: PChar; maxSizeAnswer: integer): integer; cdecl; external DLLNAME;
function JL_GetBufPtr(imageName: PChar; answer: PChar; maxSizeAnswer: integer): Pointer; cdecl; external DLLNAME;


De Functie
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function GetImage (imageName: string; bmp: TBitmap): string;
var h : THANDLE;
    charBuffer : PChar;
begin
  GetMem (charBuffer, BUFSIZE);
  h := JL_GetImage (PChar(imageName), charBuffer, BUFSIZE);
  result := RemoveTimeMsg(charBuffer);
  if (h <> 0) then
  begin
    if (not bmp.Empty) then bmp.FreeImage;
    bmp.Handle := h;
    bmp.Dormant;
    bmp.FreeImage;
  end;
  FreeMem (charBuffer, BUFSIZE);
end;


Het betref the DLL functie JL_GetImage. Deze functie geef je de naam van de image mee zoals "pietje" , status string en een buffer size. Deze geeft dan een Handler terug voor een image.

Mijn conversie tot zo ver naar C#
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;

namespace Lengtemetingen
{
    public class doDLL
    {
        [DllImport("JL_VisionLib_DLL.dll",CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)]
        public static extern long JL_GetImage(string imageName,string answer , int maxSizeAnswer);

    }
    public class Connection
    {
            string sendstatus = "";

            const int BUFFSIZE = 1024;

            public Connection(GUI gui)
            {
                try
                {

                    long test = doDLL.JL_GetImage("lut",sendstatus,BUFFSIZE);
                    
                    Console.WriteLine(test.ToString());
                }
                catch(System.DllNotFoundException dnfe)
                {
                    gui.setStatus(dnfe.Message);
                }
                catch(System.Exception exp)
                {
                    Console.WriteLine(exp.Message);
                }
            }
        }
    }


Zover ik weet in conversie is dat een THANDLE in Delphi in C# een long is. Als die een long is geeft hij ook een groot getal terug. Dit getal bij de laatste keer dat ik het startte : 16325552944185344
Als ik ipv een long IntPtr neer zet krijg ik 0 terug. Dit mede denk ik omdat het getal te groot is . Kan hij niet omzetten en dus geeft hij 0 terug.

Mijn vraag ik hoe moet ik het zo krijgen dat ik deze handler ook daadwerkelijk kan gebruiken in C#
Ik heb me blauw gezocht met google maar heb daar ook niets kunnen vinden. Alle voorbeeld die dan over DLL's gaan geven zoals het moet een Handler terug als integer en niet als long

Acties:
  • 0 Henk 'm!

  • Ozzy
  • Registratie: April 2000
  • Laatst online: 18-09 17:09

Ozzy

omnia mutantur, nihil interit

Een Delphi THandle is een longword. En in .NET is dat een System.UInt32. Wellicht even met die types proberen.
Die waarde die jij noemt is volgens mij nooit de waarde van een Handle omdat die waarde veels te groot is.

[ Voor 33% gewijzigd door Ozzy op 07-11-2006 16:25 ]

omnia mutantur, nihil interit


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat van de waarde had ik ook gezien dat ie vrij groot was en vandaar dat ook al die voorbeelden de handle als int hebben . Maar (nu heb ik niet al het verstand van Delphi) lijkt het erop dat het voor delphi wel gelijk een handler is :S

Maar zal het nakijken.. bedankt

Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Werkt je toevallig met een 64-bits Windows ofzo? Dan klopt het dat in .NET een handle zo'n groot getal is, omdat handles dan ook 64-bits worden :)

Gebruik liever een SafeHandle. Ook al gebruik je wel een 32-bits Windows. SafeHandle is een managed type en kunnen dus geen onverwachtte dingen mee gebruiken, zoals die bij 32<->64 zouden kunnen gebeuren.

Ozzy, in .NET is een handle dus NIET een System.UInt32, maar echt een apart type.

日本!🎌


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Heb 64 bit processor maar gebruik gewoon WinXP 32 bit . Maar zou misschien kunnen ..
Ik zal een kijken naar die SafeHandle. Misschien kan het me helpen .
Had namelijk ipv long er een UInt32 van gemaakt maar dan krijg ik weer gewoon 0 terug.
Bedankt voor de tip

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb de oplossing.
Dit is wat het uiteindelijk werd om de handler toch goed terug te krijgen
Voor de mensen de problemen hebben bij DLLs importeren
Hoofdzakelijk lag het aan het volgende .. de long moest IntPtr worden wat ik verwachte
Maar de return string (answer) in dit geval moest een StringBuilder zijn.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;

namespace Lengtemetingen
{
    public class doDLL
    {
        [DllImport("JL_VisionLib_DLL.dll",CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)]
        public static extern IntPtr JL_GetImage(string imageName,StringBuilder answer , int maxSizeAnswer);

    }
    public class Connection
    {
            

            const int BUFFSIZE = 1024;
            SrtingBuilder sendstatus = new StringBuilder(BUFFSIZE);
            public Connection(GUI gui)
            {
                try
                {

                    IntPtr test = doDLL.JL_GetImage("lut",sendstatus,BUFFSIZE);
                    Bitmap plaatje = Bitmap.FromHbitmap(test);
                    
                    PictureBox picbox = new PictureBox();
                    picbox.image = plaatje;
                }
                catch(System.DllNotFoundException dnfe)
                {
                    gui.setStatus(dnfe.Message);
                }
                catch(System.Exception exp)
                {
                    Console.WriteLine(exp.Message);
                }
            }
        }
    }
}

[ Voor 5% gewijzigd door Verwijderd op 09-11-2006 12:36 ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Dat komt omdat er in de string waarschijnlijk geschreven wordt. In unsafe code zou je er ook een string* mee kunnen geven die naar een gealoceerd stukje geheugen wijst.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Klopt inderdaad. :D
Pagina: 1