#c_sharp #delphi #ipc
Запущено два приложения. Одно на c#, второе на delphi Необходимо передать число из c# в delphi. Как сделать даже не знаю, гуглил, говорят через dll или оперативную память, запись и считывание файла.
Ответы
Ответ 1
Примерно так например (средствами SendMessage WM_COPYDATA): Отправка: Type TSendForm = Class(TForm) btnSend: TButton; edtNumber: TEdit; procedure btnSendClick(Sender: TObject); Private { Private-Deklarationen } Public { Public-Deklarationen } End; Const CMD_SETNUMBER = 1; //Задаем ID команды Var SendForm: TSendForm; Implementation {$R *.dfm} Procedure TSendForm.btnSendClick(Sender: TObject); Var CDS: TCopyDataStruct; Begin //Устанавливаем тип команды CDS.dwData := CMD_SETNUMBER; //Устанавливаем длину передаваемых данных CDS.cbData := Length(edtNumber.Text) + 1; //Выделяем память буфера для передачи данных GetMem(CDS.lpData, CDS.cbData); Try //Копируем данные в буфер StrPCopy(CDS.lpData, AnsiString(edtNumber.Text)); //Отсылаем сообщение в окно с заголовком StringReceiver SendMessage(FindWindow(Nil, 'Receiver'), WM_COPYDATA, Handle, Integer(@CDS)); Finally //Высвобождаем буфер FreeMem(CDS.lpData, CDS.cbData); End; End; End. Обработка: Type TRecvForm = Class(TForm) mLog: TMemo; Private FNumber: Integer; //Обработчик сообщения WM_COPYDATA Procedure WMCopyData(Var MessageData: TWMCopyData); Message WM_COPYDATA; Public Property Number: Integer Read FNumber Write FNumber; End; Const CMD_SETNUMBER = 1; Var RecvForm: TRecvForm; Implementation {$R *.dfm} Procedure TRecvForm.WMCopyData(Var MessageData: TWMCopyData); Begin If MessageData.CopyDataStruct.dwData = CMD_SETNUMBER Then Begin Try Number := StrToInt(String(PAnsiChar((MessageData.CopyDataStruct.lpData)))); Except On E: Exception Do Begin mLog.Lines.Append(Format('Ошибка: %s', [E.Message])); MessageData.Result := 0; Exit; End; End; mLog.Lines.Append(Format('Получено число: %d', [Number])); MessageData.Result := 1; End Else MessageData.Result := 0; End; End. Соответственно одно из них реализуете на C#Ответ 2
Сделал так: using System.Runtime.InteropServices; using System.Security; class ProgramSend { public const int WM_COPYDATA = 0x004A; [return: MarshalAs(UnmanagedType.Bool)] [DllImport("user32.dll")] public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern IntPtr SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); [DllImport("user32.dll", EntryPoint = "FindWindow")] public static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct MyStruct { public double coins; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string status; } public static IntPtr IntPtrAlloc(T param) { IntPtr retval = Marshal.AllocHGlobal(Marshal.SizeOf(param)); Marshal.StructureToPtr(param, retval, false); return (retval); } public static void IntPtrFree(IntPtr preAllocated) { if (IntPtr.Zero == preAllocated) throw (new Exception("Go Home")); Marshal.FreeHGlobal(preAllocated); preAllocated = IntPtr.Zero; } [StructLayout(LayoutKind.Sequential)] public struct COPYDATASTRUCT { public IntPtr dwData; // Specifies data to be passed public int cbData; // Specifies the data size in bytes public IntPtr lpData; // Pointer to data to be passed } [SuppressUnmanagedCodeSecurity] public class NativeMethod { [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); } } public static class MyCalss { public static System.String MyFunc(string sMsg) { IntPtr hTargetWnd = ProgramSend.NativeMethod.FindWindow(null, "CCDemo"); if (hTargetWnd == IntPtr.Zero) { MessageBox.Show("Unable to find the \"ReceiverMainForm\" window", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } try { ProgramSend.COPYDATASTRUCT cds = new ProgramSend.COPYDATASTRUCT(); cds.dwData = (IntPtr)1; //some data cds.cbData = sMsg.Length + 1; cds.lpData = Marshal.StringToCoTaskMemAnsi(sMsg); ProgramSend.NativeMethod.SendMessage(hTargetWnd, ProgramSend.WM_COPYDATA, IntPtr.Zero, ref cds); Marshal.FreeCoTaskMem(cds.lpData); int result = Marshal.GetLastWin32Error(); if (result != 0) { MessageBox.Show(String.Format( "SendMessage(WM_COPYDATA) failed w/err 0x{0:X}", result)); } } finally { //Marshal.FreeHGlobal(pMyStruct); } return "done"; } } На делфи: type TMyRecord = packed record coins: Double; status: string[255]; end; PMyRecord = ^TMyRecord; procedure TFMain.WMCOPYDATA(var msg: TWMCopyData); var coins: Double; status: String[255]; sText: String; begin status:=Pansichar(msg.CopyDataStruct.lpData); coins := msg.CopyDataStruct.dwData; ShowMessage('Msg: ' + status + ' Number: ' + FloatToStr(coins)); end;
Комментариев нет:
Отправить комментарий