Avatar billede brian0905 Nybegynder
06. juli 2004 - 13:53 Der er 14 kommentarer og
1 løsning

konverter intptr til globlt handle

Når jeg allokerer hukommelse til unmanaged kode får jeg en IntPtr retur, for at kunne sende denne pointer til et andet program skal den konverteres til et globalt handle, hvordan laver man denne konvertering???
Avatar billede arne_v Ekspert
06. juli 2004 - 14:04 #1
Øh - er IntPtr ikke en handle ?

Fra docs:

A platform-specific type that is used to represent a pointer or a handle.

...

The IntPtr type is designed to be an integer whose size is platform-specific. That is, an instance of this type is expected to be 32-bits on 32-bit hardware and operating systems, and 64-bits on 64-bit hardware and operating systems.

The IntPtr type can be used by languages that support pointers, and as a common means of referring to data between languages that do and do not support pointers.

IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System.IO.FileStream class to hold file handles.
Avatar billede brian0905 Nybegynder
06. juli 2004 - 14:14 #2
IntPtr er åbenbart ikke et globalt handle, sender jeg det til en anden applikation så melder denne applikatin om "invalid handle"
Avatar billede brian0905 Nybegynder
06. juli 2004 - 14:43 #3
Ser alligevel ud til at IntPtr er et globalt handle. Mit problem ser ud til at være i IPC mellem en C# applikation samt en Delphi applikation, gennem hukommelsen.... det ser ikke ud til at jeg griber det korrekt an...
Avatar billede arne_v Ekspert
06. juli 2004 - 17:40 #4
Hvordan gribder du det an ?
Avatar billede arne_v Ekspert
06. juli 2004 - 17:40 #5
griber
Avatar billede brian0905 Nybegynder
07. juli 2004 - 14:28 #6
Jeg har forsøgt at lave det på denne måde:

Applikation 1 allokerer noget hukommelse og får et handle dertil.
Applikation 1 skriver data i det stykke hukommelse.
Applikation 1 sender en message (SendMessage) til Applikation 2, hvor WParam er handlet
Applikation 2 Læser Handle fra WM_USER+X message
Applikation 2 Læser værdi fra hukommelse ud fra Handlet

Det ville ikke helt virke, det er til at lave et Automatiseret Software Test System med. Som det ser ud nu har vi valgt at lave det på en ikke så fed måde (App1 skriver til regdb, send message til app2, app2 læser fra regdb)
Avatar billede arne_v Ekspert
07. juli 2004 - 16:59 #7
Mit gæt er at du får sendt pointeren korrekt over (at den har samme
numeriske værdi i Delphi), men at den peger på det rene garbage.

Som jeg læser docs så kalder .NET Marshal.AllocHGlobal Win32 GlobalAlloc
som på trods af navnet ikke allokerer global memory.

Men man skal kalde Win32 CreateFileMapping for at allokere global memory.
Avatar billede brian0905 Nybegynder
08. juli 2004 - 11:28 #8
For mig ser det ud til i dokumentationen at den skal bruge en tmp fil eller lignende. Jeg ville allerhelst lave IPC gennem hukommelsen og ikke gennem en fil. Hvis det er mig der er forkert på den, kan du så flække et hurtigt eksempel sammen der viser hvordan man gør det til hukommelsen?
Avatar billede arne_v Ekspert
08. juli 2004 - 11:32 #9
Jeg mener at man kan sende INVALID_HANDLE_VALUE som værdi til hFile.

Jeg kan muligvis prøve at lave et eksempel i aften.
Avatar billede arne_v Ekspert
08. juli 2004 - 23:26 #10
Her kommer et eksempel.
Avatar billede arne_v Ekspert
08. juli 2004 - 23:27 #11
using System;
using System.Runtime.InteropServices;

class MainClass
{
    const int PAGE_READONLY = 0x0002;
    const int PAGE_READWRITE = 0x0004;
    const int PAGE_EXECUTE = 0x0010;
    const int PAGE_EXECUTE_READ = 0x0020;
    const int PAGE_EXECUTE_READWRITE = 0x0040;
    const int PAGE_GUARD = 0x0100;
    const int PAGE_NOACCESS = 0x0001;
    const int PAGE_NOCACHE = 0x0200;
    const int FILE_MAP_COPY = 0x0001;
    const int FILE_MAP_WRITE = 0x0002;
    const int FILE_MAP_READ = 0x0004;
    const int FILE_MAP_ALL_ACCESS = 0x001F;

    [StructLayout( LayoutKind.Sequential )]
    class SECURITY_ATTRIBUTES
    {
        //int nLength;
        //int lpSecurityDescriptor;
        //int bInheritHandle;
    }

    [DllImport("kernel32.dll")]
    static extern int CreateFileMappingA ( uint hFile,
                                          SECURITY_ATTRIBUTES lpFileMappigAttributes,
                                          int flProtect,
                                          int dwMaximumSizeHigh,
                                          int dwMaximumSizeLow,
                                          string lpName);
    [DllImport("kernel32.dll")]
    static extern IntPtr MapViewOfFile ( int hFileMappingObject,
                                        int dwDesiredAccess,
                                        int dwFileOffsetHigh,
                                        int dwFileOffsetLow,
                                        int dwNumberOfBytesToMap);
    [DllImport("kernel32.dll")]
    static extern int UnmapViewOfFile (IntPtr lpBaseAddress);
    [DllImport("kernel32.dll")]
    static extern int CloseHandle ( int hObject);
    public static void Main(string[] args)
    {
        int mem = CreateFileMappingA(0xFFFFFFFF, null, PAGE_READWRITE, 0, 8192, "GBLMEM");
        IntPtr data = MapViewOfFile(mem, FILE_MAP_WRITE, 0, 0, 8192);
        Console.WriteLine("Run Delphi program and press enter");
        Console.ReadLine();
        int[] data2 = new int[2048];
        Marshal.Copy( data, data2, 0, 3 );
        UnmapViewOfFile(data);
        CloseHandle(mem);
        Console.WriteLine(data2[0]);
        Console.WriteLine(data2[1]);
        Console.WriteLine(data2[2]);
    }
}
Avatar billede arne_v Ekspert
08. juli 2004 - 23:27 #12
program shrmem;

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

var
  mem : THandle;
  data : ^Integer;
  p : ^Integer;

begin
  mem := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0, 8192, 'GBLMEM');
  data := MapViewOfFile(mem, FILE_MAP_WRITE, 0, 0, 8192);
  data^ := 123;
  inc(data);
  data^ := 456;
  inc(data);
  data^ := 789;
  inc(data);
  UnmapViewOfFile(data);
  CloseHandle(mem);
end.
Avatar billede arne_v Ekspert
08. juli 2004 - 23:28 #13
Du skal muligvis bruge det lidt anderledes.

Men det her virker med at flytte 3 integers fra Delphi til C#.

Og du kan sikkert nemt rette det til så det passer til din problem stilling.
Avatar billede arne_v Ekspert
08. juli 2004 - 23:28 #14
Og et svar
Avatar billede brian0905 Nybegynder
09. juli 2004 - 07:55 #15
Tusind tak, det var lige det der manglede
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester