Wątek - dynamiczny parametr

0

Witam, kiedyś już poruszałem ten temat i wydawało mi się że go zrozumiałem,
przyszło co do czego i lipa, odszukałem stary post ale nie dał mi on wyjaśnienia...

Chciałbym przekazać do nowego wątku zmienną dynamiczną...

Napisałem przykład czegoś takiego w C i działa:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

void ThreadFunc(int *i) {
  printf("%d", *i);
  free(i);
}

void main() {
  int *i = (int*) malloc(4);
  *i = 1234;
  unsigned long tid;
  CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, i, 0, &tid);
  getchar();
}

Natomiast w Delphi ciągle wyskakuje access violation w procedurze ThreadFunc...

program Project1;

{$APPTYPE CONSOLE}

uses Windows;

type
  PInteger = ^Integer;

var
  TId: Cardinal;
  I: PInteger;

procedure ThreadFunc(P: Pointer);
begin
  WriteLn(PInteger(P)^);
  FreeMem(P);
end;

begin
  GetMem(I, 4);
  I^ := 1234;
  CreateThread(nil, 0, @ThreadFunc, I, 0, TId);
  ReadLn;
end.

Co źle robię ?

0
procedure ThreadFunc(P: Pointer);stdcall;
0
procedure ThreadFunc(P: Pointer);stdcall;

Hmm… no cóż, czuje się kompletnie zdezorientowany.
Nie wiem dlaczego to działa ale ważne że działa ;-)
Serdecznie dziękuj...

0

Hmm… no cóż, czuje się kompletnie zdezorientowany

Wątków nigdy nie używałem, ale rzut oka w pomoc i wszystko jasne ;)

lpStartAddress

The starting address of the new thread. This is typically the address of a function declared with the WINAPI calling convention that accepts a single 32-bit pointer as an argument and returns a 32-bit exit code.

0

Hmm… no cóż, czuje się kompletnie zdezorientowany.
Nie wiem dlaczego to działa ale ważne że działa ;-)
Serdecznie dziękuj...

Marooned juz zacytowal dlaczego, a ja tylko powiem, dlaczego w C zadzialalo, a w Delphi nie (w Pascalu pewnie tez by poszlo :) )
Otoz w Delphi domyslnym typem przekazywania parametrow jest register (podobne do fastcall z BCB). Pierwsze 3 parametry przekazywane sa przez rejestry, a reszta przez stos.
W stdcall wszystkie parametry przekazywane sa przez stos. Tak samo jest w cdecl uzywanym przez C. Prawdopodobnie i pascal zadzialaloby, bo tam takze przekazywane parametry sa przez stos, z tym ze w odwrotnej kolejnosci niz w stdcall i cdecl, ale poniewaz tylko 1 parametr przekazujemy, to nie ma to znaczenia.
Ciekawym jest natomiast, ze program w C sie niewykrzaczyl gdyz cdecl i stdcall maja inny sposob usuwania parametrow ze stosu po powrocie. W stdcall robi to funkcja, a w cdecl wywolujacy. Mogloby sie okazac, ze jezeli nie wywolalbys tego bezposrednio z maina a z jakiejs innej funkcji, to po powroce z tej funkcji wykrzaczylby sie.
W kazdym badz razie czytac helpa warto :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1